Skip to content

Commit

Permalink
add annotation to integrate with Tekton Results
Browse files Browse the repository at this point in the history
  - annotation :
    results.tekton.dev/recordSummaryAnnotations: |-
    {"repo": "tektoncd/results", "commit": "1a6b908",
    eventType: "pull_request",
    "pull_request-id": 6}
  - This annotation will be utilized in results to capture
    data.

Signed-off-by: Satyam Bhardwaj <[email protected]>
  • Loading branch information
Satyam Bhardwaj committed Dec 20, 2023
1 parent 3f7157d commit ab0fb30
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 3 deletions.
15 changes: 14 additions & 1 deletion pkg/kubeinteraction/labels.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kubeinteraction

import (
"fmt"
"strconv"

"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode"
Expand All @@ -19,7 +20,11 @@ const (
StateFailed = "failed"
)

func AddLabelsAndAnnotations(event *info.Event, pipelineRun *tektonv1.PipelineRun, repo *apipac.Repository, providerinfo *info.ProviderConfig) {
func AddLabelsAndAnnotations(event *info.Event, pipelineRun *tektonv1.PipelineRun, repo *apipac.Repository, providerinfo *info.ProviderConfig) error {
if event == nil {
return fmt.Errorf("nil event")
}

// Add labels on the soon to be created pipelinerun so UI/CLI can easily
// query them.
labels := map[string]string{
Expand Down Expand Up @@ -85,4 +90,12 @@ func AddLabelsAndAnnotations(event *info.Event, pipelineRun *tektonv1.PipelineRu
for k, v := range annotations {
pipelineRun.Annotations[k] = v
}

// Add annotations to PipelineRuns to integrate with Tekton Results
err := AddResultsAnnotation(event, pipelineRun)
if err != nil {
return fmt.Errorf("failed to add results annotations with error: %w", err)
}

return nil
}
3 changes: 2 additions & 1 deletion pkg/kubeinteraction/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ func TestAddLabelsAndAnnotations(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
AddLabelsAndAnnotations(tt.args.event, tt.args.pipelineRun, tt.args.repo, &info.ProviderConfig{})
err := AddLabelsAndAnnotations(tt.args.event, tt.args.pipelineRun, tt.args.repo, &info.ProviderConfig{})
assert.NilError(t, err)
assert.Assert(t, tt.args.pipelineRun.Labels[keys.URLOrg] == tt.args.event.Organization, "'%s' != %s",
tt.args.pipelineRun.Labels[keys.URLOrg], tt.args.event.Organization)
assert.Assert(t, tt.args.pipelineRun.Annotations[keys.URLOrg] == tt.args.event.Organization, "'%s' != %s",
Expand Down
41 changes: 41 additions & 0 deletions pkg/kubeinteraction/resultsannotation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package kubeinteraction

import (
"encoding/json"

"github.com/openshift-pipelines/pipelines-as-code/pkg/params/info"
tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
)

const (
resGroupName = "results.tekton.dev"
recordSummaryAnnotation = "/recordSummaryAnnotations"
)

type ResultAnnotation struct {
Repo string `json:"repo"`
Commit string `json:"commit"`
EventType string `json:"eventType"`
PullRequestID int `json:"pull_request-id,omitempty"`
}

// Add annotation to PipelineRuns produced by PaC for capturing additional
// data specific for TektonResults

Check failure on line 23 in pkg/kubeinteraction/resultsannotation.go

View check run for this annotation

Pipelines as Code / Pipelines as Code Dogfooding CI / go-testing

pkg/kubeinteraction/resultsannotation.go#L23

: Comment should end in a period (godot)
func AddResultsAnnotation(event *info.Event, pipelineRun *tektonv1.PipelineRun) error {
resultAnnotation := ResultAnnotation{
Repo: event.Repository,
Commit: event.SHA,
EventType: event.EventType,
PullRequestID: event.PullRequestNumber,
}

// convert the `resultAnnotation` sturct into JSON string
resAnnotationJSON, err := json.Marshal(resultAnnotation)
if err != nil {
return err
}
// append the result annotation
pipelineRun.Annotations[resGroupName+recordSummaryAnnotation] = string(resAnnotationJSON)

return nil
}
67 changes: 67 additions & 0 deletions pkg/kubeinteraction/resultsannotation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package kubeinteraction

import (
"encoding/json"
"testing"

"github.com/openshift-pipelines/pipelines-as-code/pkg/params/info"
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
"gotest.tools/v3/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestAddResultsAnnotation(t *testing.T) {
testCases := []struct {
name string
event *info.Event
expectedError error
}{
{
name: "Valid Event",
event: &info.Event{
Repository: "tektoncd/results",
SHA: "8789abb6",
EventType: "PR",
PullRequestNumber: 123,
},
expectedError: nil,
},
{
name: "Empty Event",
event: &info.Event{},
expectedError: nil,
},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
// Prepare test data
pipelineRun := &v1.PipelineRun{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{},
},
}
err := AddResultsAnnotation(tt.event, pipelineRun)
assert.NilError(t, err)

// If no error, check annotations
if err == nil {
// Expected result annotation
resultAnnotation := ResultAnnotation{
Repo: tt.event.Repository,
Commit: tt.event.SHA,
EventType: tt.event.EventType,
PullRequestID: tt.event.PullRequestNumber,
}
expectedJSON, err := json.Marshal(resultAnnotation)
if err != nil {
t.Fatalf("Failed to marshal expected result annotation: %v", err)
}
expectedAnnotation := string(expectedJSON)

// Check if annotation is added correctly
assert.Assert(t, pipelineRun.Annotations[resGroupName+recordSummaryAnnotation] == expectedAnnotation, "Unexpected record summary annotation. Expected: %s, Got: %s", expectedAnnotation, pipelineRun.Annotations[resGroupName+recordSummaryAnnotation])
}
})
}
}
5 changes: 4 additions & 1 deletion pkg/pipelineascode/pipelineascode.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi
}

// Add labels and annotations to pipelinerun
kubeinteraction.AddLabelsAndAnnotations(p.event, match.PipelineRun, match.Repo, p.vcx.GetConfig())
err := kubeinteraction.AddLabelsAndAnnotations(p.event, match.PipelineRun, match.Repo, p.vcx.GetConfig())
if err != nil {
p.logger.Errorf("Error adding labels/annotations to PipelineRun '%s' in namespace '%s': %v", match.PipelineRun.GetName(), match.Repo.GetNamespace(), err)
}

// if concurrency is defined then start the pipelineRun in pending state and
// state as queued
Expand Down
65 changes: 65 additions & 0 deletions test/gitea_results_annotation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//go:build e2e
// +build e2e

package test

import (
"context"
"encoding/json"
"strconv"
"testing"

"github.com/openshift-pipelines/pipelines-as-code/pkg/kubeinteraction"
tgitea "github.com/openshift-pipelines/pipelines-as-code/test/pkg/gitea"
"github.com/openshift-pipelines/pipelines-as-code/test/pkg/options"
"gotest.tools/v3/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
AnnotationPullRequest = "pipelinesascode.tekton.dev/pull-request"
AnnotationSummary = "results.tekton.dev/recordSummaryAnnotations"
)

func TestGiteaResultsAnnotations(t *testing.T) {
topts := &tgitea.TestOpts{
Regexp: successRegexp,
TargetEvent: options.PullRequestEvent,
YAMLFiles: map[string]string{
".tekton/pipeline.yaml": "testdata/pipelinerun.yaml",
},
CheckForStatus: "success",
}
defer tgitea.TestPR(t, topts)()

// assertions for checking results specific annotation in the PipelineRuns manifest here
prs, err := topts.ParamsRun.Clients.Tekton.TektonV1().PipelineRuns(topts.TargetNS).List(context.Background(), metav1.ListOptions{})
assert.NilError(t, err)
for _, pr := range prs.Items {
annotations := pr.GetAnnotations()
assert.Assert(t, annotations != nil, "Annotations should not be nil")

val, exists := annotations[AnnotationPullRequest]
if !exists {
t.Fatalf("Annotation %s does not exist", AnnotationPullRequest)
}

pullRequestNumber, err := strconv.Atoi(val)
assert.NilError(t, err)

// Assert specific annotation
resultAnnotation := kubeinteraction.ResultAnnotation{
Repo: topts.TargetNS,
Commit: topts.PullRequest.Head.Sha,
EventType: topts.TargetEvent,
PullRequestID: pullRequestNumber,
}
expectedJSON, err := json.Marshal(resultAnnotation)
assert.NilError(t, err)
expectedResultAnnotation := string(expectedJSON)

// an example of results annotation format
// results.tekton.dev/recordSummaryAnnotations:{"repo":"pac-demo","commit":"62f8c8b7e4c3fc38cfbe7fcce2660e5b95de2d9a","eventType":"pull_request","pull_request-id":7}
assert.Equal(t, annotations[AnnotationSummary], expectedResultAnnotation, "Unexpected annotation value")
}
}

0 comments on commit ab0fb30

Please sign in to comment.