Skip to content

Commit

Permalink
feat: support multiple tekton pipeline versions
Browse files Browse the repository at this point in the history
Signed-off-by: Charles-Edouard Brétéché <[email protected]>
  • Loading branch information
eddycharly committed Aug 4, 2022
1 parent 682eb8d commit be77958
Show file tree
Hide file tree
Showing 11 changed files with 14,983 additions and 75 deletions.
14,827 changes: 14,827 additions & 0 deletions config/prow/cluster/prowjob-crd/prowjob_customresourcedefinition.yaml

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions prow/apis/prowjobs/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1

import (
"context"
"encoding/json"
"errors"
"fmt"
Expand All @@ -26,6 +27,7 @@ import (
"time"

pipelinev1alpha1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Expand Down Expand Up @@ -189,6 +191,11 @@ type ProwJobSpec struct {
// https://github.com/tektoncd/pipeline
PipelineRunSpec *pipelinev1alpha1.PipelineRunSpec `json:"pipeline_run_spec,omitempty"`

// TektonPipelineRunSpec provides the basis for running the test as
// a pipeline-crd resource
// https://github.com/tektoncd/pipeline
TektonPipelineRunSpec *TektonPipelineRunSpec `json:"tekton_pipeline_run_spec,omitempty"`

// DecorationConfig holds configuration options for
// decorating PodSpecs that users provide
DecorationConfig *DecorationConfig `json:"decoration_config,omitempty"`
Expand Down Expand Up @@ -220,6 +227,20 @@ type ProwJobSpec struct {
JobQueueName string `json:"job_queue_name,omitempty"`
}

func (pjs ProwJobSpec) GetPipelineRunSpec() *pipelinev1beta1.PipelineRunSpec {
if pjs.TektonPipelineRunSpec != nil {
return pjs.TektonPipelineRunSpec.V1Beta1
}
if pjs.PipelineRunSpec != nil {
var spec pipelinev1beta1.PipelineRunSpec
// TODO(eddycharly) error management
if err := pjs.PipelineRunSpec.ConvertTo(context.TODO(), &spec); err == nil {
return &spec
}
}
return nil
}

type GitHubTeamSlug struct {
Slug string `json:"slug"`
Org string `json:"org"`
Expand Down Expand Up @@ -1060,6 +1081,11 @@ type JenkinsSpec struct {
GitHubBranchSourceJob bool `json:"github_branch_source_job,omitempty"`
}

// TektonPipelineRunSpec is optional parameters for Tekton pipeline jobs.
type TektonPipelineRunSpec struct {
V1Beta1 *pipelinev1beta1.PipelineRunSpec `json:"v1beta1,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ProwJobList is a list of ProwJob resources
Expand Down
27 changes: 27 additions & 0 deletions prow/apis/prowjobs/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 25 additions & 23 deletions prow/cmd/pipeline/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ import (
"k8s.io/test-infra/prow/pod-utils/downwardapi"

"github.com/sirupsen/logrus"
pipelinev1alpha1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
resourcev1alpha1 "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1"
untypedcorev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -259,7 +260,7 @@ func (c *controller) enqueueKey(ctx string, obj interface{}) {
ns = o.Namespace
}
c.workqueue.AddRateLimited(toKey(ctx, ns, o.Name))
case *pipelinev1alpha1.PipelineRun:
case *pipelinev1beta1.PipelineRun:
c.workqueue.AddRateLimited(toKey(ctx, o.Namespace, o.Name))
default:
logrus.Warnf("cannot enqueue unknown type %T: %v", o, obj)
Expand All @@ -270,9 +271,9 @@ func (c *controller) enqueueKey(ctx string, obj interface{}) {
type reconciler interface {
getProwJob(name string) (*prowjobv1.ProwJob, error)
patchProwJob(pj *prowjobv1.ProwJob, newpj *prowjobv1.ProwJob) (*prowjobv1.ProwJob, error)
getPipelineRun(context, namespace, name string) (*pipelinev1alpha1.PipelineRun, error)
getPipelineRun(context, namespace, name string) (*pipelinev1beta1.PipelineRun, error)
deletePipelineRun(context, namespace, name string) error
createPipelineRun(context, namespace string, b *pipelinev1alpha1.PipelineRun) (*pipelinev1alpha1.PipelineRun, error)
createPipelineRun(context, namespace string, b *pipelinev1beta1.PipelineRun) (*pipelinev1beta1.PipelineRun, error)
pipelineID(prowjobv1.ProwJob) (string, string, error)
now() metav1.Time
}
Expand All @@ -299,7 +300,7 @@ func (c *controller) patchProwJob(pj *prowjobv1.ProwJob, newpj *prowjobv1.ProwJo
return pjutil.PatchProwjob(context.TODO(), c.pjc.ProwV1().ProwJobs(c.pjNamespace()), logrus.NewEntry(logrus.StandardLogger()), *pj, *newpj)
}

func (c *controller) getPipelineRun(context, namespace, name string) (*pipelinev1alpha1.PipelineRun, error) {
func (c *controller) getPipelineRun(context, namespace, name string) (*pipelinev1beta1.PipelineRun, error) {
p, err := c.getPipelineConfig(context)
if err != nil {
return nil, err
Expand All @@ -313,16 +314,16 @@ func (c *controller) deletePipelineRun(pContext, namespace, name string) error {
if err != nil {
return err
}
return p.client.TektonV1alpha1().PipelineRuns(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
return p.client.TektonV1beta1().PipelineRuns(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
}

func (c *controller) createPipelineRun(pContext, namespace string, p *pipelinev1alpha1.PipelineRun) (*pipelinev1alpha1.PipelineRun, error) {
func (c *controller) createPipelineRun(pContext, namespace string, p *pipelinev1beta1.PipelineRun) (*pipelinev1beta1.PipelineRun, error) {
logrus.Debugf("createPipelineRun(%s,%s,%s)", pContext, namespace, p.Name)
pc, err := c.getPipelineConfig(pContext)
if err != nil {
return nil, err
}
p, err = pc.client.TektonV1alpha1().PipelineRuns(namespace).Create(context.TODO(), p, metav1.CreateOptions{})
p, err = pc.client.TektonV1beta1().PipelineRuns(namespace).Create(context.TODO(), p, metav1.CreateOptions{})
if err != nil {
return p, err
}
Expand Down Expand Up @@ -415,7 +416,7 @@ func reconcile(c reconciler, key string) error {
case finalState(pj.Status.State):
logrus.Infof("Observed finished: %s", key)
return nil
case wantPipelineRun && pj.Spec.PipelineRunSpec == nil:
case wantPipelineRun && pj.Spec.GetPipelineRunSpec() == nil:
return fmt.Errorf("nil PipelineRunSpec in ProwJob/%s", key)
case wantPipelineRun && !havePipelineRun:
id, url, err := c.pipelineID(*newpj)
Expand Down Expand Up @@ -504,7 +505,7 @@ const (
)

// prowJobStatus returns the desired state and description based on the pipeline status
func prowJobStatus(ps pipelinev1alpha1.PipelineRunStatus) (prowjobv1.ProwJobState, string) {
func prowJobStatus(ps pipelinev1beta1.PipelineRunStatus) (prowjobv1.ProwJobState, string) {
started := ps.StartTime
finished := ps.CompletionTime
pcond := ps.GetCondition(apis.ConditionSucceeded)
Expand Down Expand Up @@ -542,7 +543,7 @@ func pipelineMeta(name string, pj prowjobv1.ProwJob) metav1.ObjectMeta {
}

// makePipelineGitResource creates a pipeline git resource from prow job
func makePipelineGitResource(name string, refs prowjobv1.Refs, pj prowjobv1.ProwJob) *pipelinev1alpha1.PipelineResource {
func makePipelineGitResource(name string, refs prowjobv1.Refs, pj prowjobv1.ProwJob) *resourcev1alpha1.PipelineResource {
// Pick source URL
var sourceURL string
switch {
Expand All @@ -569,11 +570,11 @@ func makePipelineGitResource(name string, refs prowjobv1.Refs, pj prowjobv1.Prow
revision = refs.BaseRef
}

pr := pipelinev1alpha1.PipelineResource{
pr := resourcev1alpha1.PipelineResource{
ObjectMeta: pipelineMeta(name, pj),
Spec: pipelinev1alpha1.PipelineResourceSpec{
Type: pipelinev1alpha1.PipelineResourceTypeGit,
Params: []pipelinev1alpha1.ResourceParam{
Spec: resourcev1alpha1.PipelineResourceSpec{
Type: pipelinev1beta1.PipelineResourceTypeGit,
Params: []pipelinev1beta1.ResourceParam{
{
Name: "url",
Value: sourceURL,
Expand All @@ -590,22 +591,23 @@ func makePipelineGitResource(name string, refs prowjobv1.Refs, pj prowjobv1.Prow

// makePipeline creates a PipelineRun and substitutes ProwJob managed pipeline resources with ResourceSpec instead of ResourceRef
// so that we don't have to take care of potentially dangling created pipeline resources.
func makePipelineRun(pj prowjobv1.ProwJob) (*pipelinev1alpha1.PipelineRun, error) {
func makePipelineRun(pj prowjobv1.ProwJob) (*pipelinev1beta1.PipelineRun, error) {
// First validate.
if pj.Spec.PipelineRunSpec == nil {
spec := pj.Spec.GetPipelineRunSpec()
if spec == nil {
return nil, errors.New("no PipelineSpec defined")
}
buildID := pj.Status.BuildID
if buildID == "" {
return nil, errors.New("empty BuildID in status")
}
if err := config.ValidatePipelineRunSpec(pj.Spec.Type, pj.Spec.ExtraRefs, pj.Spec.PipelineRunSpec); err != nil {
if err := config.ValidatePipelineRunSpec(pj.Spec.Type, pj.Spec.ExtraRefs, spec); err != nil {
return nil, fmt.Errorf("invalid pipeline_run_spec: %w", err)
}

p := pipelinev1alpha1.PipelineRun{
p := pipelinev1beta1.PipelineRun{
ObjectMeta: pipelineMeta(pj.Name, pj),
Spec: *pj.Spec.PipelineRunSpec.DeepCopy(),
Spec: *spec.DeepCopy(),
}

// Add parameters instead of env vars.
Expand All @@ -616,10 +618,10 @@ func makePipelineRun(pj prowjobv1.ProwJob) (*pipelinev1alpha1.PipelineRun, error
for _, key := range sets.StringKeySet(env).List() {
val := env[key]
// TODO: make this handle existing values/substitutions.
p.Spec.Params = append(p.Spec.Params, pipelinev1alpha1.Param{
p.Spec.Params = append(p.Spec.Params, pipelinev1beta1.Param{
Name: key,
Value: pipelinev1alpha1.ArrayOrString{
Type: pipelinev1alpha1.ParamTypeString,
Value: pipelinev1beta1.ArrayOrString{
Type: pipelinev1beta1.ParamTypeString,
StringVal: val,
},
})
Expand Down
Loading

0 comments on commit be77958

Please sign in to comment.