Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/201-controller-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ rules:
verbs: ["create"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "create", "update", "delete"]
verbs: ["get", "delete"]
- apiGroups: ["pipelinesascode.tekton.dev"]
resources: ["repositories"]
verbs: ["get", "create", "list"]
Expand Down
2 changes: 1 addition & 1 deletion config/202-watcher-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ metadata:
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "delete"]
verbs: ["get", "create", "update", "delete"]
- apiGroups: ["pipelinesascode.tekton.dev"]
resources: ["repositories"]
verbs: ["get", "list", "update", "watch"]
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/pipelinesascode/keys/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ const (
LogURL = pipelinesascode.GroupName + "/log-url"
ExecutionOrder = pipelinesascode.GroupName + "/execution-order"
SCMReportingPLRStarted = pipelinesascode.GroupName + "/scm-reporting-plr-started"
SecretCreated = pipelinesascode.GroupName + "/secret-created"
CloneURL = pipelinesascode.GroupName + "/clone-url"
// PublicGithubAPIURL default is "https://api.github.com" but it can be overridden by X-GitHub-Enterprise-Host header.
PublicGithubAPIURL = "https://api.github.com"
GithubApplicationID = "github-application-id"
Expand Down
5 changes: 5 additions & 0 deletions pkg/kubeinteraction/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func AddLabelsAndAnnotations(event *info.Event, pipelineRun *tektonv1.PipelineRu
keys.SourceBranch: event.HeadBranch,
keys.Repository: repo.GetName(),
keys.GitProvider: providerConfig.Name,
keys.SecretCreated: "false",
keys.ControllerInfo: fmt.Sprintf(`{"name":"%s","configmap":"%s","secret":"%s", "gRepo": "%s"}`,
paramsinfo.Controller.Name, paramsinfo.Controller.Configmap, paramsinfo.Controller.Secret, paramsinfo.Controller.GlobalRepository),
}
Expand Down Expand Up @@ -82,6 +83,10 @@ func AddLabelsAndAnnotations(event *info.Event, pipelineRun *tektonv1.PipelineRu
annotations[keys.TargetProjectID] = strconv.Itoa(int(event.TargetProjectID))
}

if event.CloneURL != "" {
annotations[keys.CloneURL] = event.CloneURL
}

if value, ok := pipelineRun.GetObjectMeta().GetAnnotations()[keys.CancelInProgress]; ok {
labels[keys.CancelInProgress] = value
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/kubeinteraction/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func TestAddLabelsAndAnnotations(t *testing.T) {
event.SHAURL = "https://url/sha"
event.HeadBranch = "pr_branch"
event.HeadURL = "https://url/pr"
event.CloneURL = "https://url/clone"

type args struct {
event *info.Event
Expand Down Expand Up @@ -81,6 +82,7 @@ func TestAddLabelsAndAnnotations(t *testing.T) {
assert.Equal(t, tt.args.pipelineRun.Annotations[keys.SourceRepoURL], tt.args.event.HeadURL)
assert.Equal(t, tt.args.pipelineRun.Annotations[keys.ControllerInfo],
fmt.Sprintf(`{"name":"%s","configmap":"%s","secret":"%s", "gRepo": "%s"}`, tt.args.controllerInfo.Name, tt.args.controllerInfo.Configmap, tt.args.controllerInfo.Secret, tt.args.controllerInfo.GlobalRepository))
assert.Equal(t, tt.args.pipelineRun.Annotations[keys.CloneURL], tt.args.event.CloneURL)
})
}
}
52 changes: 0 additions & 52 deletions pkg/pipelineascode/pipelineascode.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ import (
"github.com/openshift-pipelines/pipelines-as-code/pkg/params/triggertype"
"github.com/openshift-pipelines/pipelines-as-code/pkg/provider"
providerstatus "github.com/openshift-pipelines/pipelines-as-code/pkg/provider/status"
"github.com/openshift-pipelines/pipelines-as-code/pkg/secrets"
tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -206,7 +204,6 @@ func (p *PacRun) Run(ctx context.Context) error {
}

func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.PipelineRun, error) {
var gitAuthSecretName string
prName := match.PipelineRun.GetName()
if prName == "" {
prName = match.PipelineRun.GetGenerateName()
Expand All @@ -218,37 +215,6 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi
p.event.BaseBranch,
)

// Automatically create a secret with the token to be reused by git-clone task
if p.pacInfo.SecretAutoCreation {
if annotation, ok := match.PipelineRun.GetAnnotations()[keys.GitAuthSecret]; ok {
gitAuthSecretName = annotation
p.debugf("startPR: using git auth secret from annotation=%s", gitAuthSecretName)
} else {
return nil, fmt.Errorf("cannot get annotation %s as set on PR", keys.GitAuthSecret)
}

authSecret, err := secrets.MakeBasicAuthSecret(p.event, gitAuthSecretName)
if err != nil {
return nil, fmt.Errorf("making basic auth secret: %s has failed: %w ", gitAuthSecretName, err)
}

if err = p.k8int.CreateSecret(ctx, match.Repo.GetNamespace(), authSecret); err != nil {
// NOTE: Handle AlreadyExists errors due to etcd/API server timing issues.
// Investigation found: slow etcd response causes API server retry, resulting in
// duplicate secret creation attempts for the same PR. This is a workaround, not
// designed behavior - reuse existing secret to prevent PipelineRun failure.
if errors.IsAlreadyExists(err) {
msg := fmt.Sprintf("Secret %s already exists in namespace %s, reusing existing secret",
authSecret.GetName(), match.Repo.GetNamespace())
p.eventEmitter.EmitMessage(match.Repo, zap.WarnLevel, "RepositorySecretReused", msg)
} else {
return nil, fmt.Errorf("creating basic auth secret: %s has failed: %w ", authSecret.GetName(), err)
}
} else {
p.debugf("startPR: created git auth secret %s in namespace %s", authSecret.GetName(), match.Repo.GetNamespace())
}
}

// Add labels and annotations to pipelinerun
err := kubeinteraction.AddLabelsAndAnnotations(p.event, match.PipelineRun, match.Repo, p.vcx.GetConfig(), p.run)
if err != nil {
Expand All @@ -269,29 +235,11 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi
pr, err := p.run.Clients.Tekton.TektonV1().PipelineRuns(match.Repo.GetNamespace()).Create(ctx,
match.PipelineRun, metav1.CreateOptions{})
if err != nil {
// cleanup the gitauth secret because ownerRef isn't set when the pipelineRun creation failed
if p.pacInfo.SecretAutoCreation {
if errDelSec := p.k8int.DeleteSecret(ctx, p.logger, match.Repo.GetNamespace(), gitAuthSecretName); errDelSec != nil {
// don't overshadow the pipelineRun creation error, just log
p.logger.Errorf("removing auto created secret: %s in namespace %s has failed: %w ", gitAuthSecretName, match.Repo.GetNamespace(), errDelSec)
}
}
// we need to make difference between markdown error and normal error that goes to namespace/controller stream
return nil, fmt.Errorf("creating pipelinerun %s in namespace %s has failed.\n\nTekton Controller has reported this error: ```%w``` ", match.PipelineRun.GetGenerateName(),
match.Repo.GetNamespace(), err)
}

// update ownerRef of secret with pipelineRun, so that it gets cleanedUp with pipelineRun
if p.pacInfo.SecretAutoCreation {
err := p.k8int.UpdateSecretWithOwnerRef(ctx, p.logger, pr.Namespace, gitAuthSecretName, pr)
if err != nil {
// we still return the created PR with error, and allow caller to decide what to do with the PR, and avoid
// unneeded SIGSEGV's
return pr, fmt.Errorf("cannot update pipelinerun %s with ownerRef: %w", pr.GetGenerateName(), err)
}
p.debugf("startPR: updated secret ownerRef for pipelinerun=%s secret=%s", pr.GetName(), gitAuthSecretName)
}

// Create status with the log url
p.logger.Infof("PipelineRun %s has been created in namespace %s with status %s for SHA: %s Target Branch: %s",
pr.GetName(), match.Repo.GetNamespace(), pr.Spec.Status, p.event.SHA, p.event.BaseBranch)
Expand Down
Loading
Loading