Merge pull request #198 from camandel/cmd_disable_vars_pr
cmd: project option to disable passing variables to PR from forked repo
This commit is contained in:
commit
ec53a63053
|
@ -41,6 +41,7 @@ type projectCreateOptions struct {
|
||||||
remoteSourceName string
|
remoteSourceName string
|
||||||
skipSSHHostKeyCheck bool
|
skipSSHHostKeyCheck bool
|
||||||
visibility string
|
visibility string
|
||||||
|
passVarsToForkedPR bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var projectCreateOpts projectCreateOptions
|
var projectCreateOpts projectCreateOptions
|
||||||
|
@ -54,6 +55,7 @@ func init() {
|
||||||
flags.BoolVarP(&projectCreateOpts.skipSSHHostKeyCheck, "skip-ssh-host-key-check", "s", false, "skip ssh host key check")
|
flags.BoolVarP(&projectCreateOpts.skipSSHHostKeyCheck, "skip-ssh-host-key-check", "s", false, "skip ssh host key check")
|
||||||
flags.StringVar(&projectCreateOpts.parentPath, "parent", "", `parent project group path (i.e "org/org01" for root project group in org01, "user/user01/group01/subgroub01") or project group id where the project should be created`)
|
flags.StringVar(&projectCreateOpts.parentPath, "parent", "", `parent project group path (i.e "org/org01" for root project group in org01, "user/user01/group01/subgroub01") or project group id where the project should be created`)
|
||||||
flags.StringVar(&projectCreateOpts.visibility, "visibility", "public", `project visibility (public or private)`)
|
flags.StringVar(&projectCreateOpts.visibility, "visibility", "public", `project visibility (public or private)`)
|
||||||
|
flags.BoolVar(&projectCreateOpts.passVarsToForkedPR, "pass-vars-to-forked-pr", false, `pass variables to run even if triggered by PR from forked repo`)
|
||||||
|
|
||||||
if err := cmdProjectCreate.MarkFlagRequired("name"); err != nil {
|
if err := cmdProjectCreate.MarkFlagRequired("name"); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -96,6 +98,7 @@ func projectCreate(cmd *cobra.Command, args []string) error {
|
||||||
RepoPath: projectCreateOpts.repoPath,
|
RepoPath: projectCreateOpts.repoPath,
|
||||||
RemoteSourceName: projectCreateOpts.remoteSourceName,
|
RemoteSourceName: projectCreateOpts.remoteSourceName,
|
||||||
SkipSSHHostKeyCheck: projectCreateOpts.skipSSHHostKeyCheck,
|
SkipSSHHostKeyCheck: projectCreateOpts.skipSSHHostKeyCheck,
|
||||||
|
PassVarsToForkedPR: projectCreateOpts.passVarsToForkedPR,
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("creating project")
|
log.Infof("creating project")
|
||||||
|
|
|
@ -40,6 +40,7 @@ type projectUpdateOptions struct {
|
||||||
name string
|
name string
|
||||||
parentPath string
|
parentPath string
|
||||||
visibility string
|
visibility string
|
||||||
|
passVarsToForkedPR bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var projectUpdateOpts projectUpdateOptions
|
var projectUpdateOpts projectUpdateOptions
|
||||||
|
@ -51,6 +52,7 @@ func init() {
|
||||||
flags.StringVarP(&projectUpdateOpts.name, "name", "n", "", "project name")
|
flags.StringVarP(&projectUpdateOpts.name, "name", "n", "", "project name")
|
||||||
flags.StringVar(&projectUpdateOpts.parentPath, "parent", "", `parent project group path (i.e "org/org01" for root project group in org01, "user/user01/group01/subgroub01") or project group id where the project should be moved`)
|
flags.StringVar(&projectUpdateOpts.parentPath, "parent", "", `parent project group path (i.e "org/org01" for root project group in org01, "user/user01/group01/subgroub01") or project group id where the project should be moved`)
|
||||||
flags.StringVar(&projectUpdateOpts.visibility, "visibility", "public", `project visibility (public or private)`)
|
flags.StringVar(&projectUpdateOpts.visibility, "visibility", "public", `project visibility (public or private)`)
|
||||||
|
flags.BoolVar(&projectUpdateOpts.passVarsToForkedPR, "pass-vars-to-forked-pr", false, `pass variables to run even if triggered by PR from forked repo`)
|
||||||
|
|
||||||
if err := cmdProjectUpdate.MarkFlagRequired("ref"); err != nil {
|
if err := cmdProjectUpdate.MarkFlagRequired("ref"); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -78,6 +80,9 @@ func projectUpdate(cmd *cobra.Command, args []string) error {
|
||||||
visibility := gwapitypes.Visibility(projectUpdateOpts.visibility)
|
visibility := gwapitypes.Visibility(projectUpdateOpts.visibility)
|
||||||
req.Visibility = &visibility
|
req.Visibility = &visibility
|
||||||
}
|
}
|
||||||
|
if flags.Changed("pass-vars-to-forked-pr") {
|
||||||
|
req.PassVarsToForkedPR = &projectUpdateOpts.passVarsToForkedPR
|
||||||
|
}
|
||||||
|
|
||||||
log.Infof("updating project")
|
log.Infof("updating project")
|
||||||
project, _, err := gwclient.UpdateProject(context.TODO(), projectUpdateOpts.ref, req)
|
project, _, err := gwclient.UpdateProject(context.TODO(), projectUpdateOpts.ref, req)
|
||||||
|
|
|
@ -156,6 +156,10 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
||||||
if sender == "" {
|
if sender == "" {
|
||||||
sender = hook.Sender.Login
|
sender = hook.Sender.Login
|
||||||
}
|
}
|
||||||
|
prFromSameRepo := false
|
||||||
|
if hook.PullRequest.Base.Repo.URL == hook.PullRequest.Head.Repo.URL {
|
||||||
|
prFromSameRepo = true
|
||||||
|
}
|
||||||
whd := &types.WebhookData{
|
whd := &types.WebhookData{
|
||||||
Event: types.WebhookEventPullRequest,
|
Event: types.WebhookEventPullRequest,
|
||||||
CommitSHA: hook.PullRequest.Head.Sha,
|
CommitSHA: hook.PullRequest.Head.Sha,
|
||||||
|
@ -166,11 +170,13 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
||||||
Sender: sender,
|
Sender: sender,
|
||||||
PullRequestID: strconv.FormatInt(hook.PullRequest.ID, 10),
|
PullRequestID: strconv.FormatInt(hook.PullRequest.ID, 10),
|
||||||
PullRequestLink: hook.PullRequest.URL,
|
PullRequestLink: hook.PullRequest.URL,
|
||||||
|
PRFromSameRepo: prFromSameRepo,
|
||||||
|
|
||||||
Repo: types.WebhookDataRepo{
|
Repo: types.WebhookDataRepo{
|
||||||
Path: path.Join(hook.Repo.Owner.Username, hook.Repo.Name),
|
Path: path.Join(hook.Repo.Owner.Username, hook.Repo.Name),
|
||||||
WebURL: hook.Repo.URL,
|
WebURL: hook.Repo.URL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return whd
|
return whd
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,10 @@ func webhookDataFromPullRequest(hook *github.PullRequestEvent) (*types.WebhookDa
|
||||||
if sender == nil {
|
if sender == nil {
|
||||||
sender = hook.Sender.Login
|
sender = hook.Sender.Login
|
||||||
}
|
}
|
||||||
|
prFromSameRepo := false
|
||||||
|
if hook.PullRequest.Base.Repo.URL == hook.PullRequest.Head.Repo.URL {
|
||||||
|
prFromSameRepo = true
|
||||||
|
}
|
||||||
|
|
||||||
whd := &types.WebhookData{
|
whd := &types.WebhookData{
|
||||||
Event: types.WebhookEventPullRequest,
|
Event: types.WebhookEventPullRequest,
|
||||||
|
@ -127,6 +131,7 @@ func webhookDataFromPullRequest(hook *github.PullRequestEvent) (*types.WebhookDa
|
||||||
Sender: *sender,
|
Sender: *sender,
|
||||||
PullRequestID: strconv.Itoa(*hook.PullRequest.Number),
|
PullRequestID: strconv.Itoa(*hook.PullRequest.Number),
|
||||||
PullRequestLink: *hook.PullRequest.HTMLURL,
|
PullRequestLink: *hook.PullRequest.HTMLURL,
|
||||||
|
PRFromSameRepo: prFromSameRepo,
|
||||||
|
|
||||||
Repo: types.WebhookDataRepo{
|
Repo: types.WebhookDataRepo{
|
||||||
Path: path.Join(*hook.Repo.Owner.Login, *hook.Repo.Name),
|
Path: path.Join(*hook.Repo.Owner.Login, *hook.Repo.Name),
|
||||||
|
|
|
@ -140,7 +140,12 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
||||||
if sender == "" {
|
if sender == "" {
|
||||||
sender = hook.User.Username
|
sender = hook.User.Username
|
||||||
}
|
}
|
||||||
build := &types.WebhookData{
|
prFromSameRepo := false
|
||||||
|
if hook.ObjectAttributes.Source.URL == hook.ObjectAttributes.Target.URL {
|
||||||
|
prFromSameRepo = true
|
||||||
|
}
|
||||||
|
|
||||||
|
whd := &types.WebhookData{
|
||||||
Event: types.WebhookEventPullRequest,
|
Event: types.WebhookEventPullRequest,
|
||||||
CommitSHA: hook.ObjectAttributes.LastCommit.ID,
|
CommitSHA: hook.ObjectAttributes.LastCommit.ID,
|
||||||
SSHURL: hook.Project.SSHURL,
|
SSHURL: hook.Project.SSHURL,
|
||||||
|
@ -150,11 +155,12 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
||||||
Sender: sender,
|
Sender: sender,
|
||||||
PullRequestID: strconv.Itoa(hook.ObjectAttributes.Iid),
|
PullRequestID: strconv.Itoa(hook.ObjectAttributes.Iid),
|
||||||
PullRequestLink: hook.ObjectAttributes.URL,
|
PullRequestLink: hook.ObjectAttributes.URL,
|
||||||
|
PRFromSameRepo: prFromSameRepo,
|
||||||
|
|
||||||
Repo: types.WebhookDataRepo{
|
Repo: types.WebhookDataRepo{
|
||||||
Path: hook.Project.PathWithNamespace,
|
Path: hook.Project.PathWithNamespace,
|
||||||
WebURL: hook.Project.WebURL,
|
WebURL: hook.Project.WebURL,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return build
|
return whd
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ type CreateProjectRequest struct {
|
||||||
RemoteSourceName string
|
RemoteSourceName string
|
||||||
RepoPath string
|
RepoPath string
|
||||||
SkipSSHHostKeyCheck bool
|
SkipSSHHostKeyCheck bool
|
||||||
|
PassVarsToForkedPR bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectRequest) (*csapitypes.Project, error) {
|
func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectRequest) (*csapitypes.Project, error) {
|
||||||
|
@ -150,6 +151,7 @@ func (h *ActionHandler) CreateProject(ctx context.Context, req *CreateProjectReq
|
||||||
RepositoryPath: req.RepoPath,
|
RepositoryPath: req.RepoPath,
|
||||||
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
|
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
|
||||||
SSHPrivateKey: string(privateKey),
|
SSHPrivateKey: string(privateKey),
|
||||||
|
PassVarsToForkedPR: req.PassVarsToForkedPR,
|
||||||
}
|
}
|
||||||
|
|
||||||
h.log.Infof("creating project")
|
h.log.Infof("creating project")
|
||||||
|
@ -184,6 +186,7 @@ type UpdateProjectRequest struct {
|
||||||
ParentRef *string
|
ParentRef *string
|
||||||
|
|
||||||
Visibility *cstypes.Visibility
|
Visibility *cstypes.Visibility
|
||||||
|
PassVarsToForkedPR *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, req *UpdateProjectRequest) (*csapitypes.Project, error) {
|
func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, req *UpdateProjectRequest) (*csapitypes.Project, error) {
|
||||||
|
@ -209,6 +212,9 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, re
|
||||||
if req.Visibility != nil {
|
if req.Visibility != nil {
|
||||||
p.Visibility = *req.Visibility
|
p.Visibility = *req.Visibility
|
||||||
}
|
}
|
||||||
|
if req.PassVarsToForkedPR != nil {
|
||||||
|
p.PassVarsToForkedPR = *req.PassVarsToForkedPR
|
||||||
|
}
|
||||||
|
|
||||||
h.log.Infof("updating project")
|
h.log.Infof("updating project")
|
||||||
rp, resp, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project)
|
rp, resp, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project)
|
||||||
|
|
|
@ -338,6 +338,7 @@ type CreateRunRequest struct {
|
||||||
Tag string
|
Tag string
|
||||||
Ref string
|
Ref string
|
||||||
PullRequestID string
|
PullRequestID string
|
||||||
|
PRFromSameRepo bool
|
||||||
SSHPrivKey string
|
SSHPrivKey string
|
||||||
SSHHostKey string
|
SSHHostKey string
|
||||||
SkipSSHHostKeyCheck bool
|
SkipSSHHostKeyCheck bool
|
||||||
|
@ -429,11 +430,13 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
|
||||||
|
|
||||||
var variables map[string]string
|
var variables map[string]string
|
||||||
if req.RunType == itypes.RunTypeProject {
|
if req.RunType == itypes.RunTypeProject {
|
||||||
|
if req.RefType != itypes.RunRefTypePullRequest || req.PRFromSameRepo || req.Project.PassVarsToForkedPR {
|
||||||
var err error
|
var err error
|
||||||
variables, err = h.genRunVariables(ctx, req)
|
variables, err = h.genRunVariables(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
variables = req.Variables
|
variables = req.Variables
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
RepoPath: req.RepoPath,
|
RepoPath: req.RepoPath,
|
||||||
RemoteSourceName: req.RemoteSourceName,
|
RemoteSourceName: req.RemoteSourceName,
|
||||||
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
|
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
|
||||||
|
PassVarsToForkedPR: req.PassVarsToForkedPR,
|
||||||
}
|
}
|
||||||
|
|
||||||
project, err := h.ah.CreateProject(ctx, areq)
|
project, err := h.ah.CreateProject(ctx, areq)
|
||||||
|
@ -104,6 +105,7 @@ func (h *UpdateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
ParentRef: req.ParentRef,
|
ParentRef: req.ParentRef,
|
||||||
Visibility: visibility,
|
Visibility: visibility,
|
||||||
|
PassVarsToForkedPR: req.PassVarsToForkedPR,
|
||||||
}
|
}
|
||||||
project, err := h.ah.UpdateProject(ctx, projectRef, areq)
|
project, err := h.ah.UpdateProject(ctx, projectRef, areq)
|
||||||
if httpError(w, err) {
|
if httpError(w, err) {
|
||||||
|
@ -241,6 +243,7 @@ func createProjectResponse(r *csapitypes.Project) *gwapitypes.ProjectResponse {
|
||||||
ParentPath: r.ParentPath,
|
ParentPath: r.ParentPath,
|
||||||
Visibility: gwapitypes.Visibility(r.Visibility),
|
Visibility: gwapitypes.Visibility(r.Visibility),
|
||||||
GlobalVisibility: string(r.GlobalVisibility),
|
GlobalVisibility: string(r.GlobalVisibility),
|
||||||
|
PassVarsToForkedPR: r.PassVarsToForkedPR,
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -127,6 +127,7 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) error {
|
||||||
Branch: webhookData.Branch,
|
Branch: webhookData.Branch,
|
||||||
Tag: webhookData.Tag,
|
Tag: webhookData.Tag,
|
||||||
PullRequestID: webhookData.PullRequestID,
|
PullRequestID: webhookData.PullRequestID,
|
||||||
|
PRFromSameRepo: webhookData.PRFromSameRepo,
|
||||||
Ref: webhookData.Ref,
|
Ref: webhookData.Ref,
|
||||||
SSHPrivKey: sshPrivKey,
|
SSHPrivKey: sshPrivKey,
|
||||||
SSHHostKey: sshHostKey,
|
SSHHostKey: sshHostKey,
|
||||||
|
|
|
@ -43,6 +43,7 @@ type WebhookData struct {
|
||||||
// use a string if on some platform (current or future) some PRs id will not be numbers
|
// use a string if on some platform (current or future) some PRs id will not be numbers
|
||||||
PullRequestID string `json:"pull_request_id,omitempty"`
|
PullRequestID string `json:"pull_request_id,omitempty"`
|
||||||
PullRequestLink string `json:"link,omitempty"` // Link to pull request
|
PullRequestLink string `json:"link,omitempty"` // Link to pull request
|
||||||
|
PRFromSameRepo bool `json:"pr_from_same_repo,omitempty"`
|
||||||
|
|
||||||
Repo WebhookDataRepo `json:"repo,omitempty"`
|
Repo WebhookDataRepo `json:"repo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,6 +307,8 @@ type Project struct {
|
||||||
// Webhooksecret is the secret passed to git sources that support a
|
// Webhooksecret is the secret passed to git sources that support a
|
||||||
// secret/token for signing or verifying the webhook payload
|
// secret/token for signing or verifying the webhook payload
|
||||||
WebhookSecret string `json:"webhook_secret,omitempty"`
|
WebhookSecret string `json:"webhook_secret,omitempty"`
|
||||||
|
|
||||||
|
PassVarsToForkedPR bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecretType string
|
type SecretType string
|
||||||
|
|
|
@ -21,12 +21,14 @@ type CreateProjectRequest struct {
|
||||||
RepoPath string `json:"repo_path,omitempty"`
|
RepoPath string `json:"repo_path,omitempty"`
|
||||||
RemoteSourceName string `json:"remote_source_name,omitempty"`
|
RemoteSourceName string `json:"remote_source_name,omitempty"`
|
||||||
SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check,omitempty"`
|
SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check,omitempty"`
|
||||||
|
PassVarsToForkedPR bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateProjectRequest struct {
|
type UpdateProjectRequest struct {
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
ParentRef *string `json:"parent_ref,omitempty"`
|
ParentRef *string `json:"parent_ref,omitempty"`
|
||||||
Visibility *Visibility `json:"visibility,omitempty"`
|
Visibility *Visibility `json:"visibility,omitempty"`
|
||||||
|
PassVarsToForkedPR *bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectResponse struct {
|
type ProjectResponse struct {
|
||||||
|
@ -36,6 +38,7 @@ type ProjectResponse struct {
|
||||||
ParentPath string `json:"parent_path,omitempty"`
|
ParentPath string `json:"parent_path,omitempty"`
|
||||||
Visibility Visibility `json:"visibility,omitempty"`
|
Visibility Visibility `json:"visibility,omitempty"`
|
||||||
GlobalVisibility string `json:"global_visibility,omitempty"`
|
GlobalVisibility string `json:"global_visibility,omitempty"`
|
||||||
|
PassVarsToForkedPR bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectCreateRunRequest struct {
|
type ProjectCreateRunRequest struct {
|
||||||
|
|
|
@ -49,6 +49,7 @@ import (
|
||||||
"gopkg.in/src-d/go-billy.v4/osfs"
|
"gopkg.in/src-d/go-billy.v4/osfs"
|
||||||
"gopkg.in/src-d/go-git.v4"
|
"gopkg.in/src-d/go-git.v4"
|
||||||
gitconfig "gopkg.in/src-d/go-git.v4/config"
|
gitconfig "gopkg.in/src-d/go-git.v4/config"
|
||||||
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||||
"gopkg.in/src-d/go-git.v4/plumbing/cache"
|
"gopkg.in/src-d/go-git.v4/plumbing/cache"
|
||||||
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
||||||
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
|
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
|
||||||
|
@ -58,6 +59,8 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
giteaUser01 = "user01"
|
giteaUser01 = "user01"
|
||||||
|
giteaUser02 = "user02"
|
||||||
|
|
||||||
agolaUser01 = "user01"
|
agolaUser01 = "user01"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -447,9 +450,64 @@ func TestCreateProject(t *testing.T) {
|
||||||
createProject(ctx, t, giteaClient, gwClient)
|
createProject(ctx, t, giteaClient, gwClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateProject(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
passVarsToForkedPR bool
|
||||||
|
expected_pre bool
|
||||||
|
expected_post bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test project update with pass-vars-to-forked-pr true",
|
||||||
|
passVarsToForkedPR: true,
|
||||||
|
expected_pre: false,
|
||||||
|
expected_post: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test project update with pass-vars-to-forked-pr false",
|
||||||
|
passVarsToForkedPR: false,
|
||||||
|
expected_pre: false,
|
||||||
|
expected_post: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
dir, err := ioutil.TempDir("", "agola")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tetcd, tgitea, c := setup(ctx, t, dir)
|
||||||
|
defer shutdownGitea(tgitea)
|
||||||
|
defer shutdownEtcd(tetcd)
|
||||||
|
|
||||||
|
giteaAPIURL := fmt.Sprintf("http://%s:%s", tgitea.HTTPListenAddress, tgitea.HTTPPort)
|
||||||
|
|
||||||
|
giteaToken, token := createLinkedAccount(ctx, t, tgitea, c)
|
||||||
|
|
||||||
|
giteaClient := gitea.NewClient(giteaAPIURL, giteaToken)
|
||||||
|
gwClient := gwclient.NewClient(c.Gateway.APIExposedURL, token)
|
||||||
|
|
||||||
|
_, project := createProject(ctx, t, giteaClient, gwClient)
|
||||||
|
if project.PassVarsToForkedPR != tt.expected_pre {
|
||||||
|
t.Fatalf("expected PassVarsToForkedPR %v, got %v (pre-update)", tt.expected_pre, project.PassVarsToForkedPR)
|
||||||
|
}
|
||||||
|
project = updateProject(ctx, t, giteaClient, gwClient, project.ID, tt.passVarsToForkedPR)
|
||||||
|
if project.PassVarsToForkedPR != tt.expected_post {
|
||||||
|
t.Fatalf("expected PassVarsToForkedPR %v, got %v (port-update)", tt.expected_post, project.PassVarsToForkedPR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func createProject(ctx context.Context, t *testing.T, giteaClient *gitea.Client, gwClient *gwclient.Client) (*gitea.Repository, *gwapitypes.ProjectResponse) {
|
func createProject(ctx context.Context, t *testing.T, giteaClient *gitea.Client, gwClient *gwclient.Client) (*gitea.Repository, *gwapitypes.ProjectResponse) {
|
||||||
giteaRepo, err := giteaClient.CreateRepo(gitea.CreateRepoOption{
|
giteaRepo, err := giteaClient.CreateRepo(gitea.CreateRepoOption{
|
||||||
Name: "repo01",
|
Name: "repo01",
|
||||||
|
Private: false,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected err: %v", err)
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
@ -470,7 +528,18 @@ func createProject(ctx context.Context, t *testing.T, giteaClient *gitea.Client,
|
||||||
return giteaRepo, project
|
return giteaRepo, project
|
||||||
}
|
}
|
||||||
|
|
||||||
func push(t *testing.T, config, cloneURL, remoteToken, message string) {
|
func updateProject(ctx context.Context, t *testing.T, giteaClient *gitea.Client, gwClient *gwclient.Client, projectRef string, passVarsToForkedPR bool) *gwapitypes.ProjectResponse {
|
||||||
|
project, _, err := gwClient.UpdateProject(ctx, projectRef, &gwapitypes.UpdateProjectRequest{
|
||||||
|
PassVarsToForkedPR: util.BoolP(passVarsToForkedPR),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return project
|
||||||
|
}
|
||||||
|
|
||||||
|
func push(t *testing.T, config, cloneURL, remoteToken, message string, pushNewBranch bool) {
|
||||||
gitfs := memfs.New()
|
gitfs := memfs.New()
|
||||||
f, err := gitfs.Create(".agola/config.jsonnet")
|
f, err := gitfs.Create(".agola/config.jsonnet")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -521,6 +590,52 @@ func push(t *testing.T, config, cloneURL, remoteToken, message string) {
|
||||||
t.Fatalf("unexpected err: %v", err)
|
t.Fatalf("unexpected err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pushNewBranch {
|
||||||
|
// change worktree and push to a new branch
|
||||||
|
headRef, err := r.Head()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
ref := plumbing.NewHashReference("refs/heads/new-branch", headRef.Hash())
|
||||||
|
err = r.Storer.SetReference(ref)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err = gitfs.Create("file1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
if _, err = f.Write([]byte("my file content")); err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := wt.Add("file1"); err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
_, err = wt.Commit("add file1", &git.CommitOptions{
|
||||||
|
Author: &object.Signature{
|
||||||
|
Name: "user01",
|
||||||
|
Email: "user01@example.com",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.Push(&git.PushOptions{
|
||||||
|
RemoteName: "origin",
|
||||||
|
RefSpecs: []gitconfig.RefSpec{
|
||||||
|
gitconfig.RefSpec("refs/heads/new-branch:refs/heads/new-branch"),
|
||||||
|
},
|
||||||
|
Auth: &http.BasicAuth{
|
||||||
|
Username: giteaUser01,
|
||||||
|
Password: remoteToken,
|
||||||
|
},
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPush(t *testing.T) {
|
func TestPush(t *testing.T) {
|
||||||
|
@ -686,7 +801,7 @@ func TestPush(t *testing.T) {
|
||||||
|
|
||||||
giteaRepo, project := createProject(ctx, t, giteaClient, gwClient)
|
giteaRepo, project := createProject(ctx, t, giteaClient, gwClient)
|
||||||
|
|
||||||
push(t, tt.config, giteaRepo.CloneURL, giteaToken, tt.message)
|
push(t, tt.config, giteaRepo.CloneURL, giteaToken, tt.message, false)
|
||||||
|
|
||||||
_ = testutil.Wait(30*time.Second, func() (bool, error) {
|
_ = testutil.Wait(30*time.Second, func() (bool, error) {
|
||||||
runs, _, err := gwClient.GetRuns(ctx, nil, nil, []string{path.Join("/project", project.ID)}, nil, "", 0, false)
|
runs, _, err := gwClient.GetRuns(ctx, nil, nil, []string{path.Join("/project", project.ID)}, nil, "", 0, false)
|
||||||
|
@ -1282,3 +1397,286 @@ func TestDirectRunLogs(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPullRequest(t *testing.T) {
|
||||||
|
config := `
|
||||||
|
{
|
||||||
|
runs: [
|
||||||
|
{
|
||||||
|
name: 'run01',
|
||||||
|
tasks: [
|
||||||
|
{
|
||||||
|
name: 'task01',
|
||||||
|
runtime: {
|
||||||
|
containers: [
|
||||||
|
{
|
||||||
|
image: 'alpine/git',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
environment: {
|
||||||
|
MYPASSWORD: { from_variable: 'mypassword' },
|
||||||
|
},
|
||||||
|
steps: [
|
||||||
|
{ type: 'clone' },
|
||||||
|
{ type: 'run', command: 'echo -n $MYPASSWORD' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
when: {
|
||||||
|
ref: '#refs/pull/\\d+/head#',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
passVarsToForkedPR bool
|
||||||
|
prFromSameRepo bool
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test PR from same repowith PassVarsToForkedPR set to false",
|
||||||
|
passVarsToForkedPR: false,
|
||||||
|
prFromSameRepo: true,
|
||||||
|
expected: "mysupersecretpassword",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test PR from same repo with PassVarsToForkedPR set to true",
|
||||||
|
passVarsToForkedPR: true,
|
||||||
|
prFromSameRepo: true,
|
||||||
|
expected: "mysupersecretpassword",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test PR from forked repo with PassVarsToForkedPR set to false",
|
||||||
|
passVarsToForkedPR: false,
|
||||||
|
prFromSameRepo: false,
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test PR from forked repo with PassVarsToForkedPR set to true",
|
||||||
|
passVarsToForkedPR: true,
|
||||||
|
prFromSameRepo: false,
|
||||||
|
expected: "mysupersecretpassword",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
||||||
|
dir, err := ioutil.TempDir("", "agola")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
tetcd, tgitea, c := setup(ctx, t, dir)
|
||||||
|
defer shutdownGitea(tgitea)
|
||||||
|
defer shutdownEtcd(tetcd)
|
||||||
|
|
||||||
|
giteaAPIURL := fmt.Sprintf("http://%s:%s", tgitea.HTTPListenAddress, tgitea.HTTPPort)
|
||||||
|
|
||||||
|
giteaToken, token := createLinkedAccount(ctx, t, tgitea, c)
|
||||||
|
|
||||||
|
giteaClient := gitea.NewClient(giteaAPIURL, giteaToken)
|
||||||
|
gwClient := gwclient.NewClient(c.Gateway.APIExposedURL, token)
|
||||||
|
|
||||||
|
giteaRepo, project := createProject(ctx, t, giteaClient, gwClient)
|
||||||
|
project = updateProject(ctx, t, giteaClient, gwClient, project.ID, tt.passVarsToForkedPR)
|
||||||
|
|
||||||
|
//create project secret
|
||||||
|
secretData := map[string]string{"mypassword": "mysupersecretpassword"}
|
||||||
|
sreq := &gwapitypes.CreateSecretRequest{
|
||||||
|
Name: "mysecret",
|
||||||
|
Type: gwapitypes.SecretTypeInternal,
|
||||||
|
Data: secretData,
|
||||||
|
}
|
||||||
|
|
||||||
|
secret, _, err := gwClient.CreateProjectSecret(context.TODO(), project.ID, sreq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to create project secret: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create project variable
|
||||||
|
rvalues := []gwapitypes.VariableValueRequest{}
|
||||||
|
rvalues = append(rvalues, gwapitypes.VariableValueRequest{
|
||||||
|
SecretName: secret.Name,
|
||||||
|
SecretVar: "mypassword",
|
||||||
|
})
|
||||||
|
|
||||||
|
vreq := &gwapitypes.CreateVariableRequest{
|
||||||
|
Name: "mypassword",
|
||||||
|
Values: rvalues,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = gwClient.CreateProjectVariable(context.TODO(), project.ID, vreq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to create project variable: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.prFromSameRepo {
|
||||||
|
// create PR from branch on same repo
|
||||||
|
push(t, config, giteaRepo.CloneURL, giteaToken, "commit", true)
|
||||||
|
|
||||||
|
prOpts := gitea.CreatePullRequestOption{
|
||||||
|
Head: "new-branch",
|
||||||
|
Base: "master",
|
||||||
|
Title: "add file1 from new-branch on same repo",
|
||||||
|
}
|
||||||
|
_, err = giteaClient.CreatePullRequest(giteaUser01, "repo01", prOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to create pull request: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// create PR from forked repo
|
||||||
|
push(t, config, giteaRepo.CloneURL, giteaToken, "commit", false)
|
||||||
|
|
||||||
|
userOpts := gitea.CreateUserOption{
|
||||||
|
Username: giteaUser02,
|
||||||
|
Password: "password",
|
||||||
|
Email: "user02@example.com",
|
||||||
|
MustChangePassword: util.BoolP(false),
|
||||||
|
}
|
||||||
|
_, err := giteaClient.AdminCreateUser(userOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to create user02: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
giteaUser02Token, err := giteaClient.CreateAccessToken(giteaUser02, "password", gitea.CreateAccessTokenOption{Name: "token01"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create token for user02: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
giteaUser02Client := gitea.NewClient(giteaAPIURL, giteaUser02Token.Token)
|
||||||
|
giteaForkedRepo, err := giteaUser02Client.CreateFork(giteaUser01, "repo01", gitea.CreateForkOption{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to fork repo01: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gitfs := memfs.New()
|
||||||
|
r, err := git.Clone(memory.NewStorage(), gitfs, &git.CloneOptions{
|
||||||
|
Auth: &http.BasicAuth{
|
||||||
|
Username: giteaUser02,
|
||||||
|
Password: giteaUser02Token.Token,
|
||||||
|
},
|
||||||
|
URL: giteaForkedRepo.CloneURL,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to clone forked repo: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wt, err := r.Worktree()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
f, err := gitfs.Create("file2")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
if _, err = f.Write([]byte("file2 content")); err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := wt.Add("file2"); err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
_, err = wt.Commit("commit from user02", &git.CommitOptions{
|
||||||
|
Author: &object.Signature{
|
||||||
|
Name: giteaUser02,
|
||||||
|
Email: "user02@example.com",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.Push(&git.PushOptions{
|
||||||
|
RemoteName: "origin",
|
||||||
|
RefSpecs: []gitconfig.RefSpec{
|
||||||
|
gitconfig.RefSpec("refs/heads/master:refs/heads/master"),
|
||||||
|
},
|
||||||
|
Auth: &http.BasicAuth{
|
||||||
|
Username: giteaUser02,
|
||||||
|
Password: giteaUser02Token.Token,
|
||||||
|
},
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
prOpts := gitea.CreatePullRequestOption{
|
||||||
|
Head: "user02:master",
|
||||||
|
Base: "master",
|
||||||
|
Title: "add file1 from master on forked repo",
|
||||||
|
}
|
||||||
|
_, err = giteaUser02Client.CreatePullRequest(giteaUser01, "repo01", prOpts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to create pull request: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = testutil.Wait(30*time.Second, func() (bool, error) {
|
||||||
|
runs, _, err := gwClient.GetRuns(ctx, nil, nil, []string{path.Join("/project", project.ID)}, nil, "", 0, false)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(runs) == 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
run := runs[0]
|
||||||
|
if run.Phase != rstypes.RunPhaseFinished {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
runs, _, err := gwClient.GetRuns(ctx, nil, nil, []string{path.Join("/project", project.ID)}, nil, "", 0, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("runs: %s", util.Dump(runs))
|
||||||
|
|
||||||
|
run, _, err := gwClient.GetRun(ctx, runs[0].ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var task *gwapitypes.RunResponseTask
|
||||||
|
for _, t := range run.Tasks {
|
||||||
|
if t.Name == "task01" {
|
||||||
|
task = t
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(runs) > 0 {
|
||||||
|
run := runs[0]
|
||||||
|
if run.Phase != rstypes.RunPhaseFinished {
|
||||||
|
t.Fatalf("expected run phase %q, got %q", rstypes.RunPhaseFinished, run.Phase)
|
||||||
|
}
|
||||||
|
if run.Result != rstypes.RunResultSuccess {
|
||||||
|
t.Fatalf("expected run result %q, got %q", rstypes.RunResultSuccess, run.Result)
|
||||||
|
}
|
||||||
|
resp, err := gwClient.GetLogs(ctx, run.ID, task.ID, false, 1, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get log: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
mypassword, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read log: %v", err)
|
||||||
|
}
|
||||||
|
if tt.expected != string(mypassword) {
|
||||||
|
t.Fatalf("expected mypassword %q, got %q", tt.expected, string(mypassword))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue