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
|
||||
skipSSHHostKeyCheck bool
|
||||
visibility string
|
||||
passVarsToForkedPR bool
|
||||
}
|
||||
|
||||
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.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.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 {
|
||||
log.Fatal(err)
|
||||
|
@ -96,6 +98,7 @@ func projectCreate(cmd *cobra.Command, args []string) error {
|
|||
RepoPath: projectCreateOpts.repoPath,
|
||||
RemoteSourceName: projectCreateOpts.remoteSourceName,
|
||||
SkipSSHHostKeyCheck: projectCreateOpts.skipSSHHostKeyCheck,
|
||||
PassVarsToForkedPR: projectCreateOpts.passVarsToForkedPR,
|
||||
}
|
||||
|
||||
log.Infof("creating project")
|
||||
|
|
|
@ -37,9 +37,10 @@ var cmdProjectUpdate = &cobra.Command{
|
|||
type projectUpdateOptions struct {
|
||||
ref string
|
||||
|
||||
name string
|
||||
parentPath string
|
||||
visibility string
|
||||
name string
|
||||
parentPath string
|
||||
visibility string
|
||||
passVarsToForkedPR bool
|
||||
}
|
||||
|
||||
var projectUpdateOpts projectUpdateOptions
|
||||
|
@ -51,6 +52,7 @@ func init() {
|
|||
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.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 {
|
||||
log.Fatal(err)
|
||||
|
@ -78,6 +80,9 @@ func projectUpdate(cmd *cobra.Command, args []string) error {
|
|||
visibility := gwapitypes.Visibility(projectUpdateOpts.visibility)
|
||||
req.Visibility = &visibility
|
||||
}
|
||||
if flags.Changed("pass-vars-to-forked-pr") {
|
||||
req.PassVarsToForkedPR = &projectUpdateOpts.passVarsToForkedPR
|
||||
}
|
||||
|
||||
log.Infof("updating project")
|
||||
project, _, err := gwclient.UpdateProject(context.TODO(), projectUpdateOpts.ref, req)
|
||||
|
|
|
@ -156,6 +156,10 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
|||
if sender == "" {
|
||||
sender = hook.Sender.Login
|
||||
}
|
||||
prFromSameRepo := false
|
||||
if hook.PullRequest.Base.Repo.URL == hook.PullRequest.Head.Repo.URL {
|
||||
prFromSameRepo = true
|
||||
}
|
||||
whd := &types.WebhookData{
|
||||
Event: types.WebhookEventPullRequest,
|
||||
CommitSHA: hook.PullRequest.Head.Sha,
|
||||
|
@ -166,11 +170,13 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
|||
Sender: sender,
|
||||
PullRequestID: strconv.FormatInt(hook.PullRequest.ID, 10),
|
||||
PullRequestLink: hook.PullRequest.URL,
|
||||
PRFromSameRepo: prFromSameRepo,
|
||||
|
||||
Repo: types.WebhookDataRepo{
|
||||
Path: path.Join(hook.Repo.Owner.Username, hook.Repo.Name),
|
||||
WebURL: hook.Repo.URL,
|
||||
},
|
||||
}
|
||||
|
||||
return whd
|
||||
}
|
||||
|
|
|
@ -116,6 +116,10 @@ func webhookDataFromPullRequest(hook *github.PullRequestEvent) (*types.WebhookDa
|
|||
if sender == nil {
|
||||
sender = hook.Sender.Login
|
||||
}
|
||||
prFromSameRepo := false
|
||||
if hook.PullRequest.Base.Repo.URL == hook.PullRequest.Head.Repo.URL {
|
||||
prFromSameRepo = true
|
||||
}
|
||||
|
||||
whd := &types.WebhookData{
|
||||
Event: types.WebhookEventPullRequest,
|
||||
|
@ -127,6 +131,7 @@ func webhookDataFromPullRequest(hook *github.PullRequestEvent) (*types.WebhookDa
|
|||
Sender: *sender,
|
||||
PullRequestID: strconv.Itoa(*hook.PullRequest.Number),
|
||||
PullRequestLink: *hook.PullRequest.HTMLURL,
|
||||
PRFromSameRepo: prFromSameRepo,
|
||||
|
||||
Repo: types.WebhookDataRepo{
|
||||
Path: path.Join(*hook.Repo.Owner.Login, *hook.Repo.Name),
|
||||
|
|
|
@ -140,7 +140,12 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
|||
if sender == "" {
|
||||
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,
|
||||
CommitSHA: hook.ObjectAttributes.LastCommit.ID,
|
||||
SSHURL: hook.Project.SSHURL,
|
||||
|
@ -150,11 +155,12 @@ func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData {
|
|||
Sender: sender,
|
||||
PullRequestID: strconv.Itoa(hook.ObjectAttributes.Iid),
|
||||
PullRequestLink: hook.ObjectAttributes.URL,
|
||||
PRFromSameRepo: prFromSameRepo,
|
||||
|
||||
Repo: types.WebhookDataRepo{
|
||||
Path: hook.Project.PathWithNamespace,
|
||||
WebURL: hook.Project.WebURL,
|
||||
},
|
||||
}
|
||||
return build
|
||||
return whd
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ type CreateProjectRequest struct {
|
|||
RemoteSourceName string
|
||||
RepoPath string
|
||||
SkipSSHHostKeyCheck bool
|
||||
PassVarsToForkedPR bool
|
||||
}
|
||||
|
||||
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,
|
||||
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
|
||||
SSHPrivateKey: string(privateKey),
|
||||
PassVarsToForkedPR: req.PassVarsToForkedPR,
|
||||
}
|
||||
|
||||
h.log.Infof("creating project")
|
||||
|
@ -183,7 +185,8 @@ type UpdateProjectRequest struct {
|
|||
Name *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) {
|
||||
|
@ -209,6 +212,9 @@ func (h *ActionHandler) UpdateProject(ctx context.Context, projectRef string, re
|
|||
if req.Visibility != nil {
|
||||
p.Visibility = *req.Visibility
|
||||
}
|
||||
if req.PassVarsToForkedPR != nil {
|
||||
p.PassVarsToForkedPR = *req.PassVarsToForkedPR
|
||||
}
|
||||
|
||||
h.log.Infof("updating project")
|
||||
rp, resp, err := h.configstoreClient.UpdateProject(ctx, p.ID, p.Project)
|
||||
|
|
|
@ -338,6 +338,7 @@ type CreateRunRequest struct {
|
|||
Tag string
|
||||
Ref string
|
||||
PullRequestID string
|
||||
PRFromSameRepo bool
|
||||
SSHPrivKey string
|
||||
SSHHostKey string
|
||||
SkipSSHHostKeyCheck bool
|
||||
|
@ -429,10 +430,12 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
|
|||
|
||||
var variables map[string]string
|
||||
if req.RunType == itypes.RunTypeProject {
|
||||
var err error
|
||||
variables, err = h.genRunVariables(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
if req.RefType != itypes.RunRefTypePullRequest || req.PRFromSameRepo || req.Project.PassVarsToForkedPR {
|
||||
var err error
|
||||
variables, err = h.genRunVariables(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
variables = req.Variables
|
||||
|
|
|
@ -55,6 +55,7 @@ func (h *CreateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
|||
RepoPath: req.RepoPath,
|
||||
RemoteSourceName: req.RemoteSourceName,
|
||||
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
|
||||
PassVarsToForkedPR: req.PassVarsToForkedPR,
|
||||
}
|
||||
|
||||
project, err := h.ah.CreateProject(ctx, areq)
|
||||
|
@ -101,9 +102,10 @@ func (h *UpdateProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
|
||||
areq := &action.UpdateProjectRequest{
|
||||
Name: req.Name,
|
||||
ParentRef: req.ParentRef,
|
||||
Visibility: visibility,
|
||||
Name: req.Name,
|
||||
ParentRef: req.ParentRef,
|
||||
Visibility: visibility,
|
||||
PassVarsToForkedPR: req.PassVarsToForkedPR,
|
||||
}
|
||||
project, err := h.ah.UpdateProject(ctx, projectRef, areq)
|
||||
if httpError(w, err) {
|
||||
|
@ -235,12 +237,13 @@ func (h *ProjectHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func createProjectResponse(r *csapitypes.Project) *gwapitypes.ProjectResponse {
|
||||
res := &gwapitypes.ProjectResponse{
|
||||
ID: r.ID,
|
||||
Name: r.Name,
|
||||
Path: r.Path,
|
||||
ParentPath: r.ParentPath,
|
||||
Visibility: gwapitypes.Visibility(r.Visibility),
|
||||
GlobalVisibility: string(r.GlobalVisibility),
|
||||
ID: r.ID,
|
||||
Name: r.Name,
|
||||
Path: r.Path,
|
||||
ParentPath: r.ParentPath,
|
||||
Visibility: gwapitypes.Visibility(r.Visibility),
|
||||
GlobalVisibility: string(r.GlobalVisibility),
|
||||
PassVarsToForkedPR: r.PassVarsToForkedPR,
|
||||
}
|
||||
|
||||
return res
|
||||
|
|
|
@ -127,6 +127,7 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) error {
|
|||
Branch: webhookData.Branch,
|
||||
Tag: webhookData.Tag,
|
||||
PullRequestID: webhookData.PullRequestID,
|
||||
PRFromSameRepo: webhookData.PRFromSameRepo,
|
||||
Ref: webhookData.Ref,
|
||||
SSHPrivKey: sshPrivKey,
|
||||
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
|
||||
PullRequestID string `json:"pull_request_id,omitempty"`
|
||||
PullRequestLink string `json:"link,omitempty"` // Link to pull request
|
||||
PRFromSameRepo bool `json:"pr_from_same_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
|
||||
// secret/token for signing or verifying the webhook payload
|
||||
WebhookSecret string `json:"webhook_secret,omitempty"`
|
||||
|
||||
PassVarsToForkedPR bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||
}
|
||||
|
||||
type SecretType string
|
||||
|
|
|
@ -21,21 +21,24 @@ type CreateProjectRequest struct {
|
|||
RepoPath string `json:"repo_path,omitempty"`
|
||||
RemoteSourceName string `json:"remote_source_name,omitempty"`
|
||||
SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check,omitempty"`
|
||||
PassVarsToForkedPR bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateProjectRequest struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
ParentRef *string `json:"parent_ref,omitempty"`
|
||||
Visibility *Visibility `json:"visibility,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
ParentRef *string `json:"parent_ref,omitempty"`
|
||||
Visibility *Visibility `json:"visibility,omitempty"`
|
||||
PassVarsToForkedPR *bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectResponse struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
ParentPath string `json:"parent_path,omitempty"`
|
||||
Visibility Visibility `json:"visibility,omitempty"`
|
||||
GlobalVisibility string `json:"global_visibility,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
ParentPath string `json:"parent_path,omitempty"`
|
||||
Visibility Visibility `json:"visibility,omitempty"`
|
||||
GlobalVisibility string `json:"global_visibility,omitempty"`
|
||||
PassVarsToForkedPR bool `json:"pass_vars_to_forked_pr,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectCreateRunRequest struct {
|
||||
|
|
|
@ -49,6 +49,7 @@ import (
|
|||
"gopkg.in/src-d/go-billy.v4/osfs"
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
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/object"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/transport/http"
|
||||
|
@ -58,6 +59,8 @@ import (
|
|||
|
||||
const (
|
||||
giteaUser01 = "user01"
|
||||
giteaUser02 = "user02"
|
||||
|
||||
agolaUser01 = "user01"
|
||||
)
|
||||
|
||||
|
@ -447,9 +450,64 @@ func TestCreateProject(t *testing.T) {
|
|||
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) {
|
||||
giteaRepo, err := giteaClient.CreateRepo(gitea.CreateRepoOption{
|
||||
Name: "repo01",
|
||||
Name: "repo01",
|
||||
Private: false,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
|
@ -470,7 +528,18 @@ func createProject(ctx context.Context, t *testing.T, giteaClient *gitea.Client,
|
|||
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()
|
||||
f, err := gitfs.Create(".agola/config.jsonnet")
|
||||
if err != nil {
|
||||
|
@ -521,6 +590,52 @@ func push(t *testing.T, config, cloneURL, remoteToken, message string) {
|
|||
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) {
|
||||
|
@ -686,7 +801,7 @@ func TestPush(t *testing.T) {
|
|||
|
||||
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) {
|
||||
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