From c91870ab60c5d2bc4c76e221ff86f48a4ad8ed77 Mon Sep 17 00:00:00 2001 From: Sri Vignesh Date: Thu, 6 Mar 2025 17:21:21 +0530 Subject: [PATCH 1/2] add label for pac Signed-off-by: Sri Vignesh --- pkg/pac/pac.go | 119 +++++++++++++++++++++++++++++++++++++++++------ steps/pac/pac.go | 2 +- 2 files changed, 105 insertions(+), 16 deletions(-) diff --git a/pkg/pac/pac.go b/pkg/pac/pac.go index fea2f49c..f2293165 100644 --- a/pkg/pac/pac.go +++ b/pkg/pac/pac.go @@ -19,7 +19,6 @@ import ( "github.com/openshift-pipelines/pipelines-as-code/pkg/git" "github.com/openshift-pipelines/pipelines-as-code/pkg/params/info" "github.com/openshift-pipelines/release-tests/pkg/clients" - "github.com/openshift-pipelines/release-tests/pkg/k8s" "github.com/openshift-pipelines/release-tests/pkg/oc" "github.com/openshift-pipelines/release-tests/pkg/pipelines" "github.com/openshift-pipelines/release-tests/pkg/store" @@ -243,6 +242,36 @@ func createNewRepository(c *clients.Clients, projectName, targetGroupNamespace, return nil } +// addLabelToProject adds a label to a GitLab project +func addLabelToProject(client *gitlab.Client, projectID int, labelName, color, description string) error { + // Check if the label already exists + labels, _, err := client.Labels.ListLabels(projectID, &gitlab.ListLabelsOptions{}) + if err != nil { + return fmt.Errorf("failed to fetch project labels: %w", err) + } + + for _, label := range labels { + if label.Name == labelName { + fmt.Printf("Label '%s' already exists in project ID %d\n", labelName, projectID) + return nil + } + } + + // Create label if it doesn't exist + _, _, err = client.Labels.CreateLabel(projectID, &gitlab.CreateLabelOptions{ + Name: gitlab.Ptr(labelName), + Color: gitlab.Ptr(color), + Description: gitlab.Ptr(description), + }) + + if err != nil { + return fmt.Errorf("failed to create label '%s': %w", labelName, err) + } + + fmt.Printf("Successfully added label '%s' to project ID %d\n", labelName, projectID) + return nil +} + func SetupGitLabProject(client *gitlab.Client) *gitlab.Project { gitlabGroupNamespace := os.Getenv("GITLAB_GROUP_NAMESPACE") projectIDOrPath := os.Getenv("GITLAB_PROJECT_ID") @@ -269,9 +298,30 @@ func SetupGitLabProject(client *gitlab.Client) *gitlab.Project { testsuit.T.Fail(fmt.Errorf("failed to create repository")) } + // Add a "bug" label to the project + err = addLabelToProject(client, project.ID, "bug", "red", "Indicates a bug in the project") + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to add label to project: %w", err)) + } + return project } +// // addLabelToMergeRequest adds a label to a GitLab Merge Request +// func addLabelToMergeRequest(client *gitlab.Client, projectID int, mergeRequestIID int, label string) error { +// opts := &gitlab.UpdateMergeRequestOptions{ +// Labels: gitlab.Labels{label}, +// } + +// _, _, err := client.MergeRequests.UpdateMergeRequest(projectID, mergeRequestIID, opts) +// if err != nil { +// return fmt.Errorf("failed to add label to Merge Request: %w", err) +// } + +// fmt.Printf("Successfully added label '%s' to Merge Request #%d\n", label, mergeRequestIID) +// return nil +// } + // Create new branch to push the commit func createBranch(client *gitlab.Client, projectID int, branchName string) error { _, _, err := client.Branches.CreateBranch(projectID, &gitlab.CreateBranchOptions{ @@ -321,6 +371,39 @@ func generatePipelineRun() error { return nil } +// addAnnotationToYAML adds the specified annotation to the PipelineRun YAML +func addAnnotationToYAML(yamlContent []byte, key, value string) ([]byte, error) { + var pipelineRun map[string]interface{} + + if err := yaml.Unmarshal(yamlContent, &pipelineRun); err != nil { + return nil, fmt.Errorf("failed to parse YAML: %w", err) + } + + // Ensure metadata and annotations exist + metadata, ok := pipelineRun["metadata"].(map[string]interface{}) + if !ok { + metadata = make(map[string]interface{}) + pipelineRun["metadata"] = metadata + } + + annotations, ok := metadata["annotations"].(map[string]interface{}) + if !ok { + annotations = make(map[string]interface{}) + metadata["annotations"] = annotations + } + + // Add or update the annotation + annotations[key] = value + + // Convert back to YAML + modifiedYAML, err := yaml.Marshal(pipelineRun) + if err != nil { + return nil, fmt.Errorf("failed to serialize modified YAML: %w", err) + } + + return modifiedYAML, nil +} + // Validate generated yaml file from pac generate cmd func validateYAML(yamlContent []byte) error { var content map[string]interface{} @@ -343,7 +426,13 @@ func createCommit(client *gitlab.Client, projectID int, branch, commitMessage, f return fmt.Errorf("could not read file %s: %v", filePath, err) } - if err := validateYAML(fileContent); err != nil { + // Modify YAML to add annotation + modifiedYAML, err := addAnnotationToYAML(fileContent, "pipelinesascode.tekton.dev/on-label", "bug") + if err != nil { + return fmt.Errorf("could not add annotation: %v", err) + } + + if err := validateYAML(modifiedYAML); err != nil { return fmt.Errorf("invalid YAML content: %v", err) } @@ -353,7 +442,7 @@ func createCommit(client *gitlab.Client, projectID int, branch, commitMessage, f Branch: &branch, CommitMessage: &commitMessage, Actions: []*gitlab.CommitActionOptions{ - {Action: &action, FilePath: gitlab.Ptr(fileDesPath), Content: gitlab.Ptr(string(fileContent))}, + {Action: &action, FilePath: gitlab.Ptr(fileDesPath), Content: gitlab.Ptr(string(modifiedYAML))}, }, } @@ -477,15 +566,15 @@ func deleteGitlabProject(client *gitlab.Client, projectID int) error { return nil } -func CleanupPAC(client *gitlab.Client, c *clients.Clients, projectID int, smeeDeploymentName, namespace string) { - // Remove Forked Project - if cleanupErr := deleteGitlabProject(client, projectID); cleanupErr != nil { - testsuit.T.Fail(fmt.Errorf("cleanup failed: %v", cleanupErr)) - } - - // Delete Smee Deployment - err := k8s.DeleteDeployment(c, namespace, smeeDeploymentName) - if err != nil { - testsuit.T.Fail(fmt.Errorf("failed to Delete Smee Deployment: %v", err)) - } -} +// func CleanupPAC(client *gitlab.Client, c *clients.Clients, projectID int, smeeDeploymentName, namespace string) { +// // Remove Forked Project +// if cleanupErr := deleteGitlabProject(client, projectID); cleanupErr != nil { +// testsuit.T.Fail(fmt.Errorf("cleanup failed: %v", cleanupErr)) +// } + +// // Delete Smee Deployment +// err := k8s.DeleteDeployment(c, namespace, smeeDeploymentName) +// if err != nil { +// testsuit.T.Fail(fmt.Errorf("failed to Delete Smee Deployment: %v", err)) +// } +// } diff --git a/steps/pac/pac.go b/steps/pac/pac.go index 8037fc84..8e34dd1d 100644 --- a/steps/pac/pac.go +++ b/steps/pac/pac.go @@ -22,5 +22,5 @@ var _ = gauge.Step("Configure GitLab repo and validate pipelinerun", func() { project := pac.SetupGitLabProject(client) pipelineName := pac.ConfigurePreviewChanges(client, project.ID) pipelines.ValidatePipelineRun(store.Clients(), pipelineName, "successful", "no", store.Namespace()) - pac.CleanupPAC(client, store.Clients(), project.ID, store.GetScenarioData("smee_deployment_name"), store.Namespace()) + // pac.CleanupPAC(client, store.Clients(), project.ID, store.GetScenarioData("smee_deployment_name"), store.Namespace()) }) From 324ef78ffcfb632539c0fd5becb4269cf9892125 Mon Sep 17 00:00:00 2001 From: Sri Vignesh Date: Thu, 6 Mar 2025 21:27:01 +0530 Subject: [PATCH 2/2] pac on-label Signed-off-by: Sri Vignesh --- pkg/pac/pac.go | 289 +++++++++++++++++++++++--------------- specs/pac/pac-gitlab.spec | 50 ++++++- steps/pac/pac.go | 41 ++++-- 3 files changed, 258 insertions(+), 122 deletions(-) diff --git a/pkg/pac/pac.go b/pkg/pac/pac.go index f2293165..b9fc41bd 100644 --- a/pkg/pac/pac.go +++ b/pkg/pac/pac.go @@ -19,6 +19,7 @@ import ( "github.com/openshift-pipelines/pipelines-as-code/pkg/git" "github.com/openshift-pipelines/pipelines-as-code/pkg/params/info" "github.com/openshift-pipelines/release-tests/pkg/clients" + "github.com/openshift-pipelines/release-tests/pkg/k8s" "github.com/openshift-pipelines/release-tests/pkg/oc" "github.com/openshift-pipelines/release-tests/pkg/pipelines" "github.com/openshift-pipelines/release-tests/pkg/store" @@ -30,19 +31,23 @@ import ( ) const ( - filePath = "pull-request.yaml" initialBackoffDuration = 5 * time.Second - mainBranch = "main" maxRetriesForkProject = 5 maxRetriesPipelineStatus = 10 targetURL = "http://pipelines-as-code-controller.openshift-pipelines:8080" webhookConfigName = "gitlab-webhook-config" ) -func CreateGitLabSecret() { +var client *gitlab.Client + +func SetGitLabClient(c *gitlab.Client) { + client = c +} + +// Initialize Gitlab Client +func InitGitLabClient() *gitlab.Client { tokenSecretData := os.Getenv("GITLAB_TOKEN") webhookSecretData := os.Getenv("GITLAB_WEBHOOK_TOKEN") - store.PutScenarioData("GITLAB_WEBHOOK_TOKEN", webhookSecretData) if tokenSecretData == "" && webhookSecretData == "" { testsuit.T.Fail(fmt.Errorf("token for authorization to the GitLab repository was not exported as a system variable")) } else { @@ -51,8 +56,14 @@ func CreateGitLabSecret() { } else { log.Printf("Secret \"%s\" already exists", webhookConfigName) } - store.PutScenarioData("gitlabToken", tokenSecretData) } + store.PutScenarioData("GITLAB_WEBHOOK_TOKEN", webhookSecretData) + client, err := gitlab.NewClient(tokenSecretData) + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to initialize GitLab client: %v", err)) + } + + return client } func getNewSmeeURL() (string, error) { @@ -140,7 +151,7 @@ func createSmeeDeployment(c *clients.Clients, namespace, smeeURL string) error { func SetupSmeeDeployment() { var err error smeeDeploymentName := "gosmee-client" - store.PutScenarioData("smee_deployment_name", smeeDeploymentName) + store.PutScenarioData("smeeDeploymentName", smeeDeploymentName) smeeURL, err := getNewSmeeURL() if err != nil { @@ -153,19 +164,8 @@ func SetupSmeeDeployment() { } } -// Initialize Gitlab Client -func InitGitLabClient() *gitlab.Client { - token := store.GetScenarioData("gitlabToken") - client, err := gitlab.NewClient(token) - if err != nil { - testsuit.T.Fail(fmt.Errorf("failed to initialize GitLab client: %v", err)) - } - - return client -} - // Specified Gitlab Project ID is forked into Group Namespace -func forkProject(client *gitlab.Client, projectID, targetNamespace string) (*gitlab.Project, error) { +func forkProject(projectID, targetNamespace string) (*gitlab.Project, error) { for i := 0; i < maxRetriesForkProject; i++ { projectName := fmt.Sprintf("release-tests-fork-%08d", time.Now().UnixNano()%1e8) project, _, err := client.Projects.ForkProject(projectID, &gitlab.ForkProjectOptions{ @@ -184,7 +184,7 @@ func forkProject(client *gitlab.Client, projectID, targetNamespace string) (*git } // Add WebhookURL to forked Project -func addWebhook(client *gitlab.Client, projectID int, webhookURL, token string) error { +func addWebhook(projectID int, webhookURL, token string) error { pushEvents := true mergeRequestsEvents := true noteEvents := true @@ -243,7 +243,7 @@ func createNewRepository(c *clients.Clients, projectName, targetGroupNamespace, } // addLabelToProject adds a label to a GitLab project -func addLabelToProject(client *gitlab.Client, projectID int, labelName, color, description string) error { +func addLabelToProject(projectID int, labelName, color, description string) error { // Check if the label already exists labels, _, err := client.Labels.ListLabels(projectID, &gitlab.ListLabelsOptions{}) if err != nil { @@ -272,7 +272,7 @@ func addLabelToProject(client *gitlab.Client, projectID int, labelName, color, d return nil } -func SetupGitLabProject(client *gitlab.Client) *gitlab.Project { +func SetupGitLabProject() *gitlab.Project { gitlabGroupNamespace := os.Getenv("GITLAB_GROUP_NAMESPACE") projectIDOrPath := os.Getenv("GITLAB_PROJECT_ID") @@ -283,12 +283,12 @@ func SetupGitLabProject(client *gitlab.Client) *gitlab.Project { smeeURL := store.GetScenarioData("SMEE_URL") webhookToken := store.GetScenarioData("GITLAB_WEBHOOK_TOKEN") - project, err := forkProject(client, projectIDOrPath, gitlabGroupNamespace) + project, err := forkProject(projectIDOrPath, gitlabGroupNamespace) if err != nil { testsuit.T.Fail(fmt.Errorf("error during project forking: %w", err)) } - err = addWebhook(client, project.ID, smeeURL, webhookToken) + err = addWebhook(project.ID, smeeURL, webhookToken) if err != nil { testsuit.T.Fail(fmt.Errorf("failed to add webhook: %w", err)) } @@ -297,33 +297,55 @@ func SetupGitLabProject(client *gitlab.Client) *gitlab.Project { if err != nil { testsuit.T.Fail(fmt.Errorf("failed to create repository")) } + store.PutScenarioData("projectID", strconv.Itoa(project.ID)) + + return project +} - // Add a "bug" label to the project - err = addLabelToProject(client, project.ID, "bug", "red", "Indicates a bug in the project") +// adds a comment to the specified merge request. +func AddComment(comment string) error { + + projectID, _ := strconv.Atoi(store.GetScenarioData("projectID")) + mrID, _ := strconv.Atoi(store.GetScenarioData("mrID")) + opts := &gitlab.CreateMergeRequestNoteOptions{ + Body: gitlab.Ptr(comment), + } + + _, _, err := client.Notes.CreateMergeRequestNote(projectID, mrID, opts) if err != nil { - testsuit.T.Fail(fmt.Errorf("failed to add label to project: %w", err)) + return fmt.Errorf("failed to add comment to MR %d in project %d: %v", mrID, projectID, err) } - return project + return nil } -// // addLabelToMergeRequest adds a label to a GitLab Merge Request -// func addLabelToMergeRequest(client *gitlab.Client, projectID int, mergeRequestIID int, label string) error { -// opts := &gitlab.UpdateMergeRequestOptions{ -// Labels: gitlab.Labels{label}, -// } +func AddLabel(label, color, description string) error { -// _, _, err := client.MergeRequests.UpdateMergeRequest(projectID, mergeRequestIID, opts) -// if err != nil { -// return fmt.Errorf("failed to add label to Merge Request: %w", err) -// } + projectID, _ := strconv.Atoi(store.GetScenarioData("projectID")) + mrID, _ := strconv.Atoi(store.GetScenarioData("mrID")) -// fmt.Printf("Successfully added label '%s' to Merge Request #%d\n", label, mergeRequestIID) -// return nil -// } + // Add a label to the project + err := addLabelToProject(projectID, label, color, description) + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to add label to project: %w", err)) + } + // Create a LabelOptions instance + addLabels := gitlab.LabelOptions{label} + + // Update the merge request to add the label + _, _, err = client.MergeRequests.UpdateMergeRequest(projectID, mrID, &gitlab.UpdateMergeRequestOptions{ + AddLabels: &addLabels, + }) + if err != nil { + return fmt.Errorf("failed to update merge request with label 'bug': %w", err) + } + + fmt.Printf("Successfully added label %s to merge request %d\n", label, mrID) + return nil +} // Create new branch to push the commit -func createBranch(client *gitlab.Client, projectID int, branchName string) error { +func createBranch(projectID int, branchName string) error { _, _, err := client.Branches.CreateBranch(projectID, &gitlab.CreateBranchOptions{ Branch: gitlab.Ptr(branchName), Ref: gitlab.Ptr("main"), @@ -331,20 +353,20 @@ func createBranch(client *gitlab.Client, projectID int, branchName string) error return err } -func createPacGenerateOpts() *pacgenerate.Opts { +func createPacGenerateOpts(eventType, branch, fileName string) *pacgenerate.Opts { // Initialize PAC generate options opts := pacgenerate.MakeOpts() // Set Event information opts.Event = &info.Event{ - EventType: "pull_request", - BaseBranch: mainBranch, + EventType: eventType, + BaseBranch: branch, } // Set Project URL and Branch name to GitInfo // ProjectURL is used as PipelineRun name with suffix opts.GitInfo = &git.Info{ URL: store.GetScenarioData("PROJECT_URL"), - Branch: mainBranch, + Branch: branch, } // Initialize I/O streams var outputBuffer bytes.Buffer @@ -354,14 +376,14 @@ func createPacGenerateOpts() *pacgenerate.Opts { In: os.Stdin, } // Specify the FileName of the pipelinerun yaml - opts.FileName = filePath + opts.FileName = fileName return opts } // Generate sample PipelineRun, pull-request.yaml -func generatePipelineRun() error { - opts := createPacGenerateOpts() +func generatePipelineRun(eventType, branch, fileName string) error { + opts := createPacGenerateOpts(eventType, branch, fileName) err := pacgenerate.Generate(opts, true) if err != nil { @@ -371,82 +393,96 @@ func generatePipelineRun() error { return nil } -// addAnnotationToYAML adds the specified annotation to the PipelineRun YAML -func addAnnotationToYAML(yamlContent []byte, key, value string) ([]byte, error) { - var pipelineRun map[string]interface{} +// Validate generated yaml file from pac generate cmd +func validateYAML(yamlContent []byte) error { + var content map[string]interface{} - if err := yaml.Unmarshal(yamlContent, &pipelineRun); err != nil { - return nil, fmt.Errorf("failed to parse YAML: %w", err) + err := yaml.Unmarshal(yamlContent, &content) + if err != nil { + return fmt.Errorf("invalid YAML format: %v", err) } - // Ensure metadata and annotations exist - metadata, ok := pipelineRun["metadata"].(map[string]interface{}) - if !ok { - metadata = make(map[string]interface{}) - pipelineRun["metadata"] = metadata - } + return nil +} - annotations, ok := metadata["annotations"].(map[string]interface{}) - if !ok { - annotations = make(map[string]interface{}) - metadata["annotations"] = annotations - } +func GeneratePipelineRunYaml(eventType, branch string) error { + fileName := eventType + ".yaml" - // Add or update the annotation - annotations[key] = value + // Generate the PipelineRun YAML. + if err := generatePipelineRun(eventType, branch, fileName); err != nil { + return fmt.Errorf("could not generate PipelineRun in %s: %v", fileName, err) + } - // Convert back to YAML - modifiedYAML, err := yaml.Marshal(pipelineRun) + fileContent, err := os.ReadFile(fileName) if err != nil { - return nil, fmt.Errorf("failed to serialize modified YAML: %w", err) + return fmt.Errorf("could not read file %s: %v", fileName, err) } - return modifiedYAML, nil -} - -// Validate generated yaml file from pac generate cmd -func validateYAML(yamlContent []byte) error { - var content map[string]interface{} - - err := yaml.Unmarshal(yamlContent, &content) - if err != nil { - return fmt.Errorf("invalid YAML format: %v", err) + if err := validateYAML(fileContent); err != nil { + return fmt.Errorf("invalid YAML content: %v", err) } + store.PutScenarioData("fileContent", string(fileContent)) + store.PutScenarioData("branch", string(branch)) + store.PutScenarioData("fileName", string(fileName)) return nil } -func createCommit(client *gitlab.Client, projectID int, branch, commitMessage, fileDesPath string) error { - err := generatePipelineRun() +// updateAnnotation updates the specified annotation in the pull-request.yaml file +func UpdateAnnotation(annotationKey, annotationValue string) error { + fileName := store.GetScenarioData("fileName") + data, err := os.ReadFile(fileName) if err != nil { - return fmt.Errorf("could not generate PipelineRun in %s: %v", filePath, err) + return fmt.Errorf("failed to read YAML file: %v", err) } - fileContent, err := os.ReadFile(filePath) - if err != nil { - return fmt.Errorf("could not read file %s: %v", filePath, err) + + var content map[string]interface{} + if err := yaml.Unmarshal(data, &content); err != nil { + return fmt.Errorf("failed to unmarshal YAML: %v", err) + } + + meta := content["metadata"].(map[interface{}]interface{}) + anns := meta["annotations"].(map[interface{}]interface{}) + + // If the annotation exists, append the new value; otherwise, set it. + if currValue, exists := anns[annotationKey].(string); exists { + anns[annotationKey] = currValue + " " + annotationValue + } else { + anns[annotationKey] = annotationValue } - // Modify YAML to add annotation - modifiedYAML, err := addAnnotationToYAML(fileContent, "pipelinesascode.tekton.dev/on-label", "bug") + out, err := yaml.Marshal(content) if err != nil { - return fmt.Errorf("could not add annotation: %v", err) + return fmt.Errorf("failed to marshal YAML: %v", err) } - if err := validateYAML(modifiedYAML); err != nil { + if err := os.WriteFile(fileName, out, 0644); err != nil { + return fmt.Errorf("failed to write YAML file: %v", err) + } + + if err := validateYAML(out); err != nil { return fmt.Errorf("invalid YAML content: %v", err) } + store.PutScenarioData("fileContent", string(out)) + + fmt.Println("Annotation updated successfully") + return nil +} + +func createCommit(projectID int, branch, commitMessage, fileDesPath string) error { // Commit the PAC generated PLR + fileContent := store.GetScenarioData("fileContent") action := gitlab.FileCreate commitOpts := &gitlab.CreateCommitOptions{ Branch: &branch, CommitMessage: &commitMessage, Actions: []*gitlab.CommitActionOptions{ - {Action: &action, FilePath: gitlab.Ptr(fileDesPath), Content: gitlab.Ptr(string(modifiedYAML))}, + {Action: &action, FilePath: gitlab.Ptr(fileDesPath), Content: gitlab.Ptr(fileContent)}, }, } - _, _, err = client.Commits.CreateCommit(projectID, commitOpts) + _, _, err := client.Commits.CreateCommit(projectID, commitOpts) if err != nil { return fmt.Errorf("failed to create commit: %v", err) } @@ -454,7 +490,7 @@ func createCommit(client *gitlab.Client, projectID int, branch, commitMessage, f } // Creates MR to a forked project with a PipelineRun YAML under .tekton directory -func createMergeRequest(client *gitlab.Client, projectID int, sourceBranch, targetBranch, title string) (string, error) { +func createMergeRequest(projectID int, sourceBranch, targetBranch, title string) (string, error) { mrOptions := &gitlab.CreateMergeRequestOptions{ SourceBranch: &sourceBranch, TargetBranch: &targetBranch, @@ -486,7 +522,7 @@ func isTerminalStatus(status string) bool { return status == "success" || status == "failed" || status == "canceled" } -func checkPipelineStatus(client *gitlab.Client, projectID, mergeRequestID int) error { +func checkPipelineStatus(projectID, mergeRequestID int) error { var retryCount int // Fetch pipelines for the specified MergeRequest ID @@ -520,20 +556,26 @@ func checkPipelineStatus(client *gitlab.Client, projectID, mergeRequestID int) e } } -func ConfigurePreviewChanges(client *gitlab.Client, projectID int) string { +func ConfigurePreviewChanges() { randomSuffix := strconv.FormatInt(time.Now().UnixNano(), 10)[:8] branchName := "preview-branch-" + randomSuffix commitMessage := "Add preview changes for feature" + fileDesPath := ".tekton/pull-request.yaml" + + projectID, err := strconv.Atoi(store.GetScenarioData("projectID")) + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to convert project ID to integer: %v", err)) + } - if err := createBranch(client, projectID, branchName); err != nil { + if err := createBranch(projectID, branchName); err != nil { testsuit.T.Fail(fmt.Errorf("failed to create branch: %v", err)) } - if err := createCommit(client, projectID, branchName, commitMessage, ".tekton/pull-request.yaml"); err != nil { + if err := createCommit(projectID, branchName, commitMessage, fileDesPath); err != nil { testsuit.T.Fail(fmt.Errorf("failed to create commit: %v", err)) } - mrURL, err := createMergeRequest(client, projectID, branchName, "main", "Add preview changes for feature") + mrURL, err := createMergeRequest(projectID, branchName, "main", "Add preview changes for feature") if err != nil { testsuit.T.Fail(fmt.Errorf("failed to create merge request: %v", err)) } @@ -545,19 +587,32 @@ func ConfigurePreviewChanges(client *gitlab.Client, projectID int) string { testsuit.T.Fail(fmt.Errorf("failed to extract merge request ID: %v", err)) } - err = checkPipelineStatus(client, projectID, mrID) + store.PutScenarioData("mrID", strconv.Itoa(mrID)) +} + +func GetPipelineNameFromMR() (pipelineName string) { + projectID, err := strconv.Atoi(store.GetScenarioData("projectID")) + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to convert project ID to integer: %v", err)) + } + mrID, err := strconv.Atoi(store.GetScenarioData("mrID")) + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to convert project ID to integer: %v", err)) + } + + err = checkPipelineStatus(projectID, mrID) if err != nil { testsuit.T.Fail(fmt.Errorf("failed to check pipeline status: %v", err)) } - pipelineName, err := pipelines.GetLatestPipelinerun(store.Clients(), store.Namespace()) + pipelineName, err = pipelines.GetLatestPipelinerun(store.Clients(), store.Namespace()) if err != nil { testsuit.T.Fail(fmt.Errorf("failed to get the latest Pipelinerun: %v", err)) } return pipelineName } -func deleteGitlabProject(client *gitlab.Client, projectID int) error { +func deleteGitlabProject(projectID int) error { _, err := client.Projects.DeleteProject(projectID) if err != nil { return fmt.Errorf("failed to delete project: %w", err) @@ -566,15 +621,27 @@ func deleteGitlabProject(client *gitlab.Client, projectID int) error { return nil } -// func CleanupPAC(client *gitlab.Client, c *clients.Clients, projectID int, smeeDeploymentName, namespace string) { -// // Remove Forked Project -// if cleanupErr := deleteGitlabProject(client, projectID); cleanupErr != nil { -// testsuit.T.Fail(fmt.Errorf("cleanup failed: %v", cleanupErr)) -// } - -// // Delete Smee Deployment -// err := k8s.DeleteDeployment(c, namespace, smeeDeploymentName) -// if err != nil { -// testsuit.T.Fail(fmt.Errorf("failed to Delete Smee Deployment: %v", err)) -// } -// } +func CleanupPAC(c *clients.Clients, smeeDeploymentName, namespace string) { + // Remove the generated PipelineRun YAML file + fileName := store.GetScenarioData("fileName") + if fileName != "" { + if err := os.Remove(fileName); err != nil { + testsuit.T.Fail(fmt.Errorf("failed to remove file %s: %v", fileName, err)) + } + } + + projectID, err := strconv.Atoi(store.GetScenarioData("projectID")) + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to convert project ID to integer: %v", err)) + } + // Remove Forked Project + if cleanupErr := deleteGitlabProject(projectID); cleanupErr != nil { + testsuit.T.Fail(fmt.Errorf("cleanup failed: %v", cleanupErr)) + } + + // Delete Smee Deployment + err = k8s.DeleteDeployment(c, namespace, smeeDeploymentName) + if err != nil { + testsuit.T.Fail(fmt.Errorf("failed to Delete Smee Deployment: %v", err)) + } +} diff --git a/specs/pac/pac-gitlab.spec b/specs/pac/pac-gitlab.spec index 21a4cca8..51248596 100644 --- a/specs/pac/pac-gitlab.spec +++ b/specs/pac/pac-gitlab.spec @@ -11,7 +11,53 @@ Importance: Critical This scenario tests configuring PAC in Public GitLab project Steps: - * Configure GitLab token for PAC tests + * Setup Gitlab Client * Verify ServiceAccount "pipeline" exist * Create Smee deployment - * Configure GitLab repo and validate pipelinerun + * Configure GitLab repo for "pull_request" in "main" + * Configure PipelineRun + * Validate PipelineRun for "success" + * Cleanup PAC + +## Configure PAC in GitLab Project: PIPELINES-30-TC02 +Tags: pac, sanity, e2e +Component: PAC +Level: Integration +Type: Functional +Importance: Critical + +This scenario tests on-label annotation in PAC + +Steps: + * Setup Gitlab Client + * Verify ServiceAccount "pipeline" exist + * Create Smee deployment + * Configure GitLab repo for "pull_request" in "main" + * Update Annotation "pipelinesascode.tekton.dev/on-label" with "[bug]" + * Configure PipelineRun + * "0" pipelinerun(s) should be present within "10" seconds + * Add Label Name "bug" with "red" color with description "Identify a Issue" + * Validate PipelineRun for "success" + * Cleanup PAC + +## Configure PAC in GitLab Project: PIPELINES-30-TC03 +Tags: pac, sanity, e2e +Component: PAC +Level: Integration +Type: Functional +Importance: Critical + +This scenario tests on-comment annotation in PAC + +Steps: + * Setup Gitlab Client + * Verify ServiceAccount "pipeline" exist + * Create Smee deployment + * Configure GitLab repo for "pull_request" in "main" + * Update Annotation "pipelinesascode.tekton.dev/on-comment" with "^/hello-world" + * Configure PipelineRun + * Validate PipelineRun for "success" + * Add Comment in MR "/hello-world" + * "2" pipelinerun(s) should be present within "10" seconds + * Validate PipelineRun for "success" + * Cleanup PAC diff --git a/steps/pac/pac.go b/steps/pac/pac.go index 8e34dd1d..659d3404 100644 --- a/steps/pac/pac.go +++ b/steps/pac/pac.go @@ -8,19 +8,42 @@ import ( "github.com/openshift-pipelines/release-tests/pkg/store" ) -var _ = gauge.Step("Configure GitLab token for PAC tests", func() { - pac.CreateGitLabSecret() +var _ = gauge.Step("Setup Gitlab Client", func() { + c := pac.InitGitLabClient() + pac.SetGitLabClient(c) }) var _ = gauge.Step("Create Smee deployment", func() { pac.SetupSmeeDeployment() - k8s.ValidateDeployments(store.Clients(), store.Namespace(), store.GetScenarioData("smee_deployment_name")) + k8s.ValidateDeployments(store.Clients(), store.Namespace(), store.GetScenarioData("smeeDeploymentName")) }) -var _ = gauge.Step("Configure GitLab repo and validate pipelinerun", func() { - client := pac.InitGitLabClient() - project := pac.SetupGitLabProject(client) - pipelineName := pac.ConfigurePreviewChanges(client, project.ID) - pipelines.ValidatePipelineRun(store.Clients(), pipelineName, "successful", "no", store.Namespace()) - // pac.CleanupPAC(client, store.Clients(), project.ID, store.GetScenarioData("smee_deployment_name"), store.Namespace()) +var _ = gauge.Step("Configure GitLab repo for in ", func(eventType, branch string) { + pac.SetupGitLabProject() + pac.GeneratePipelineRunYaml(eventType, branch) +}) + +var _ = gauge.Step("Configure PipelineRun", func() { + pac.ConfigurePreviewChanges() +}) + +var _ = gauge.Step("Validate PipelineRun for ", func(state string) { + pipelineName := pac.GetPipelineNameFromMR() + pipelines.ValidatePipelineRun(store.Clients(), pipelineName, state, "no", store.Namespace()) +}) + +var _ = gauge.Step("Update Annotation with ", func(annotationKey, annotationValue string) { + pac.UpdateAnnotation(annotationKey, annotationValue) +}) + +var _ = gauge.Step("Add Comment in MR ", func(comment string) { + pac.AddComment(comment) +}) + +var _ = gauge.Step("Add Label Name with color with description ", func(labelName, color, description string) { + pac.AddLabel(labelName, color, description) +}) + +var _ = gauge.Step("Cleanup PAC", func() { + pac.CleanupPAC(store.Clients(), store.GetScenarioData("smeeDeploymentName"), store.Namespace()) })