diff --git a/.ct.yaml b/.ct.yaml index 952b8b0b..cec5553d 100644 --- a/.ct.yaml +++ b/.ct.yaml @@ -1,3 +1,4 @@ helm-extra-args: --timeout 180s chart-repos: - stable=https://charts.helm.sh/stable +validate-maintainers: false diff --git a/README.md b/README.md index 7928b94a..dedd6f0c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ At the moment, the following artifacts kinds are supported *(with plans to suppo - [Kyverno policies](https://kyverno.io) - [OLM operators](https://github.com/operator-framework) - [Open Policy Agent (OPA) policies](https://www.openpolicyagent.org/) -- [Tekton tasks and pipelines](https://tekton.dev/) +- [Tekton tasks, pipelines and stepactions](https://tekton.dev/) - [Tinkerbell actions](https://tinkerbell.org/) You can use Artifact Hub to: diff --git a/charts/artifact-hub/Chart.yaml b/charts/artifact-hub/Chart.yaml index 97cfaedd..aaee10a3 100644 --- a/charts/artifact-hub/Chart.yaml +++ b/charts/artifact-hub/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: artifact-hub description: Artifact Hub is a web-based application that enables finding, installing, and publishing Kubernetes packages. type: application -version: 1.17.1-0 +version: 1.17.1-1 appVersion: 1.17.0 kubeVersion: ">= 1.19.0-0" home: https://artifacthub.io diff --git a/charts/artifact-hub/values.schema.json b/charts/artifact-hub/values.schema.json index ac80f47c..ec13c53f 100644 --- a/charts/artifact-hub/values.schema.json +++ b/charts/artifact-hub/values.schema.json @@ -1162,7 +1162,7 @@ }, "repositoriesKinds": { "title": "Repositories kinds to process ([] = all)", - "description": "The following kinds are supported at the moment: falco, helm, olm, opa, tbaction, krew, helm-plugin, tekton-task, keda-scaler, coredns, keptn, tekton-pipeline, container, kubewarden, gatekeeper, kyverno, knative-client-plugin, backstage, argo-template, kubearmor, kcl, headlamp, inspektor-gadget", + "description": "The following kinds are supported at the moment: falco, helm, olm, opa, tbaction, krew, helm-plugin, tekton-task, keda-scaler, coredns, keptn, tekton-pipeline, container, kubewarden, gatekeeper, kyverno, knative-client-plugin, backstage, argo-template, kubearmor, kcl, headlamp, inspektor-gadget, tekton-stepaction", "type": "array", "items": { "type": "string" diff --git a/cmd/ah/lint.go b/cmd/ah/lint.go index c56721c0..f82d17ce 100644 --- a/cmd/ah/lint.go +++ b/cmd/ah/lint.go @@ -90,7 +90,7 @@ func newLintCmd() *cobra.Command { return lint(opts, &output{cmd.OutOrStdout()}) }, } - lintCmd.Flags().StringVarP(&opts.kind, "kind", "k", "helm", "repository kind: argo-template, backstage, coredns, falco, gatekeeper, headlamp, helm, helm-plugin, inspektor-gadget, kcl, keda-scaler, keptn, knative-client-plugin, krew, kubearmor, kubewarden, kyverno, olm, opa, tbaction, tekton-task, tekton-pipeline") + lintCmd.Flags().StringVarP(&opts.kind, "kind", "k", "helm", "repository kind: argo-template, backstage, coredns, falco, gatekeeper, headlamp, helm, helm-plugin, inspektor-gadget, kcl, keda-scaler, keptn, knative-client-plugin, krew, kubearmor, kubewarden, kyverno, olm, opa, tbaction, tekton-task, tekton-pipeline, tekton-stepaction") lintCmd.Flags().StringVarP(&opts.path, "path", "p", ".", "repository's packages path") return lintCmd } @@ -134,7 +134,7 @@ func lint(opts *lintOptions, out *output) error { report = lintKrew(opts.path) case hub.OLM: report = lintOLM(opts.path) - case hub.TektonTask, hub.TektonPipeline: + case hub.TektonTask, hub.TektonPipeline, hub.TektonStepAction: report = lintTekton(opts.path, kind) default: return errors.New("kind not supported yet") @@ -376,9 +376,9 @@ func lintOLM(basePath string) *lintReport { return report } -// lintTekton checks if the Tekton tasks or pipelines available in the path -// provided are ready to be processed by the Tekton tracker source and listed -// on Artifact Hub. +// lintTekton checks if the Tekton tasks, pipelines or stepactions available in +// the path provided are ready to be processed by the Tekton tracker source and +// listed on Artifact Hub. func lintTekton(basePath string, kind hub.RepositoryKind) *lintReport { report := &lintReport{} repository := &hub.Repository{ diff --git a/database/migrations/schema/057_tekton_stepactions.sql b/database/migrations/schema/057_tekton_stepactions.sql new file mode 100644 index 00000000..07322d4d --- /dev/null +++ b/database/migrations/schema/057_tekton_stepactions.sql @@ -0,0 +1,5 @@ +insert into repository_kind values (23, 'Tekton stepactions'); + +---- create above / drop below ---- + +delete from repository_kind where repository_kind_id = 23; diff --git a/database/tests/schema/schema.sql b/database/tests/schema/schema.sql index 8d525a5f..9f77bbe1 100644 --- a/database/tests/schema/schema.sql +++ b/database/tests/schema/schema.sql @@ -564,7 +564,8 @@ select results_eq( (19, 'KubeArmor policies'), (20, 'KCL modules'), (21, 'Headlamp plugins'), - (22, 'Inspektor gadgets') + (22, 'Inspektor gadgets'), + (23, 'Tekton stepactions') $$, 'Repository kinds should exist' ); diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index 0cff89c7..898fb2aa 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -1621,6 +1621,30 @@ paths: $ref: "#/components/responses/TooManyRequests" "500": $ref: "#/components/responses/InternalServerError" + "/packages/tekton-stepaction/{repoName}/{packageName}": + get: + tags: + - Packages + summary: Get package details + description: Get package details + operationId: getTektonStepActionDetails + parameters: + - $ref: "#/components/parameters/RepoNameParam" + - $ref: "#/components/parameters/PackageNameParam" + responses: + "200": + description: "" + content: + application/json: + schema: + $ref: "#/components/schemas/TektonStepActionPackage" + "404": + $ref: "#/components/responses/NotFoundResponse" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" + "/packages/tekton-task/{repoName}/{packageName}": get: tags: @@ -2172,6 +2196,30 @@ paths: $ref: "#/components/responses/TooManyRequests" "500": $ref: "#/components/responses/InternalServerError" + "/packages/tekton-stepaction/{repoName}/{packageName}/{version}": + get: + tags: + - Packages + summary: Get package version details + description: Get package version details + operationId: getTektonStepActionVersionDetails + parameters: + - $ref: "#/components/parameters/RepoNameParam" + - $ref: "#/components/parameters/PackageNameParam" + - $ref: "#/components/parameters/VersionParam" + responses: + "200": + description: "" + content: + application/json: + schema: + $ref: "#/components/schemas/TektonStepActionPackage" + "404": + $ref: "#/components/responses/NotFoundResponse" + "429": + $ref: "#/components/responses/TooManyRequests" + "500": + $ref: "#/components/responses/InternalServerError" "/packages/tekton-task/{repoName}/{packageName}/{version}": get: tags: @@ -4396,6 +4444,32 @@ components: type: string nullable: false example: darwin/amd64 + TektonStepActionPackage: + allOf: + - $ref: "#/components/schemas/Package" + - type: object + properties: + data: + type: object + properties: + pipelines.minVersion: + type: string + example: 2.0.0 + manifestRaw: + type: string + additionalProperties: + type: string + example: "apiVersion: tekton.dev/v1beta1" + examples: + type: object + nullable: false + additionalProperties: true + platforms: + type: array + items: + type: string + nullable: false + example: darwin/amd64 TektonTaskPackage: allOf: - $ref: "#/components/schemas/Package" @@ -4832,6 +4906,7 @@ components: * `20` - KCL packages * `21` - Headlamp plugins * `22` - Inspektor gadgets + * `23` - Tekton stepactions RepositoryKindParam: type: string enum: @@ -4858,6 +4933,7 @@ components: - kcl - headlamp - inspektor-gadget + - tekton-stepaction description: | Repository kind name: * `helm` - Helm charts @@ -4883,6 +4959,7 @@ components: * `kcl` - KCL packages * `headlamp` - Headlamp plugins * `inspektor-gadget` - Inspektor gadgets + * `tekton-stepaction` - Tekton stepactions RepositorySummary: type: object required: @@ -5425,6 +5502,7 @@ components: * `20` - KCL packages * `21` - Headlamp plugins * `22` - Inspektor gadgets + * `23` - Tekton stepactions PackageNameParam: in: path name: packageName diff --git a/docs/repositories.md b/docs/repositories.md index 50cda202..228ba1b8 100644 --- a/docs/repositories.md +++ b/docs/repositories.md @@ -25,6 +25,7 @@ The following repositories kinds are supported at the moment: - [OPA policies repositories](https://github.com/artifacthub/hub/blob/master/docs/opa_policies_repositories.md) - [Tekton pipelines repositories](https://github.com/artifacthub/hub/blob/master/docs/tekton_pipelines_repositories.md) - [Tekton tasks repositories](https://github.com/artifacthub/hub/blob/master/docs/tekton_tasks_repositories.md) +- [Tekton stepactions repositories](https://github.com/artifacthub/hub/blob/master/docs/tekton_stepactions_repositories.md) - [Tinkerbell actions repositories](https://github.com/artifacthub/hub/blob/master/docs/tinkerbell_actions_repositories.md) This guide also contains additional information about the following repositories topics: diff --git a/docs/security_report.md b/docs/security_report.md index c25c74d4..f37b0711 100644 --- a/docs/security_report.md +++ b/docs/security_report.md @@ -18,9 +18,9 @@ Artifact Hub will try to extract the containers images used by Helm charts from The images used by an OLM operator are extracted from the `containerImage` annotation in the [CSV file metadata section](https://github.com/operator-framework/community-operators/blob/master/docs/packaging-required-fields.md), as well as from the `related images` section in the CSV spec. Most of the OLM operators currently listed in Artifact Hub provide that information already, so security reports for them are already available in Artifact Hub with no extra effort required. -### Tekton tasks and pipelines +### Tekton tasks, pipelines and stepactions -The images used by Tekton tasks and pipelines are extracted from the [`task.step.image`](https://github.com/tektoncd/pipeline/blob/main/docs/tasks.md#running-scripts-within-steps) fields of the resource yaml file. If the `image` value is specified by [`params`](https://github.com/tektoncd/pipeline/blob/main/docs/tasks.md#specifying-parameters), the default value of the params (if provided) is used to run the security report. You can find examples with explanations [here](https://github.com/tektoncd/community/blob/main/teps/0079-tekton-catalog-support-tiers.md#extract-container-images-from-catalogs). Please note that the security reports do not include user-provided container images if the default value of the image `params` are overwritten by `pipelineRun` or `taskRun` at run time. +The images used by Tekton tasks, pipelines and stepactions are extracted from the [`task.step.image`](https://github.com/tektoncd/pipeline/blob/main/docs/tasks.md#running-scripts-within-steps) fields of the resource yaml file. If the `image` value is specified by [`params`](https://github.com/tektoncd/pipeline/blob/main/docs/tasks.md#specifying-parameters), the default value of the params (if provided) is used to run the security report. You can find examples with explanations [here](https://github.com/tektoncd/community/blob/main/teps/0079-tekton-catalog-support-tiers.md#extract-container-images-from-catalogs). Please note that the security reports do not include user-provided container images if the default value of the image `params` are overwritten by `pipelineRun` or `taskRun` at run time. ### CoreDNS plugins, KEDA scalers, Keptn integrations, OPA policies and Tinkerbell actions diff --git a/docs/tekton_stepactions_repositories.md b/docs/tekton_stepactions_repositories.md new file mode 100644 index 00000000..a1fac6f5 --- /dev/null +++ b/docs/tekton_stepactions_repositories.md @@ -0,0 +1,3 @@ +## Tekton stepactions repositories + +Tekton stepactions repositories are expected to follow the same rules as Tekton tasks repositories. Please see the [Tekton tasks repositories](https://github.com/artifacthub/hub/blob/master/docs/tekton_tasks_repositories.md) documentation for more details. diff --git a/docs/www/headers/tekton_stepactions_repositories b/docs/www/headers/tekton_stepactions_repositories new file mode 100644 index 00000000..ef6e1fc9 --- /dev/null +++ b/docs/www/headers/tekton_stepactions_repositories @@ -0,0 +1,6 @@ +--- +title: "Tekton stepactions" +aliases: [ + "/tekton_stepactions_repositories", +] +--- diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 60e140ad..7695f7cc 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -265,7 +265,7 @@ func (h *Handlers) setupRouter() { r.Get("/stats", h.Packages.GetStats) r.With(corsMW).Get("/search", h.Packages.Search) r.With(h.Users.RequireLogin).Get("/starred", h.Packages.GetStarredByUser) - r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget$}/{repoName}/{packageName}", func(r chi.Router) { + r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget|^tekton-stepaction$}/{repoName}/{packageName}", func(r chi.Router) { r.Get("/feed/rss", h.Packages.RssFeed) r.With(corsMW).Get("/summary", h.Packages.GetSummary) r.Get("/{version}", h.Packages.Get) @@ -430,7 +430,7 @@ func (h *Handlers) setupRouter() { // Index special entry points r.Route("/packages", func(r chi.Router) { - r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget$}/{repoName}/{packageName}", func(r chi.Router) { + r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget|^tekton-stepaction$}/{repoName}/{packageName}", func(r chi.Router) { r.With(h.Packages.InjectIndexMeta).Get("/{version}", h.Static.Index) r.With(h.Packages.InjectIndexMeta).Get("/", h.Static.Index) }) diff --git a/internal/handlers/pkg/handlers_test.go b/internal/handlers/pkg/handlers_test.go index 36571337..1faaa5c6 100644 --- a/internal/handlers/pkg/handlers_test.go +++ b/internal/handlers/pkg/handlers_test.go @@ -2177,6 +2177,17 @@ func TestBuildURL(t *testing.T) { "2.0.0", baseURL + "/packages/inspektor-gadget/repo1/pkg1/2.0.0", }, + { + &hub.Package{ + NormalizedName: "pkg1", + Repository: &hub.Repository{ + Kind: hub.TektonStepAction, + Name: "repo1", + }, + }, + "2.0.0", + baseURL + "/packages/tekton-stepaction/repo1/pkg1/2.0.0", + }, } for _, tc := range testCases { tc := tc diff --git a/internal/hub/repo.go b/internal/hub/repo.go index 25eaed2c..145a5b90 100644 --- a/internal/hub/repo.go +++ b/internal/hub/repo.go @@ -115,6 +115,9 @@ const ( // InspektorGadget represents a repository with Inspektor Gadgets. InspektorGadget RepositoryKind = 22 + + // TektonStepAction represents a repository with Tekton stepactions. + TektonStepAction RepositoryKind = 23 ) // GetKindName returns the name of the provided repository kind. @@ -166,6 +169,8 @@ func GetKindName(kind RepositoryKind) string { return "tekton-pipeline" case TektonTask: return "tekton-task" + case TektonStepAction: + return "tekton-stepaction" default: return "" } @@ -221,6 +226,8 @@ func GetKindFromName(kind string) (RepositoryKind, error) { return TektonPipeline, nil case "tekton-task": return TektonTask, nil + case "tekton-stepaction": + return TektonStepAction, nil default: return -1, errors.New("invalid kind name") } diff --git a/internal/repo/manager.go b/internal/repo/manager.go index 0854d098..e7d71eed 100644 --- a/internal/repo/manager.go +++ b/internal/repo/manager.go @@ -101,6 +101,7 @@ var ( hub.TBAction, hub.TektonPipeline, hub.TektonTask, + hub.TektonStepAction, } ) @@ -300,7 +301,8 @@ func (m *Manager) ClaimOwnership(ctx context.Context, repoName, orgName string) hub.OPA, hub.TBAction, hub.TektonPipeline, - hub.TektonTask: + hub.TektonTask, + hub.TektonStepAction: tmpDir, packagesPath, err := m.rc.CloneRepository(ctx, r) if err != nil { return err @@ -480,7 +482,8 @@ func (m *Manager) locateMetadataFile(r *hub.Repository, basePath string) string hub.OPA, hub.TBAction, hub.TektonPipeline, - hub.TektonTask: + hub.TektonTask, + hub.TektonStepAction: mdFile = filepath.Join(basePath, hub.RepositoryMetadataFile) } return mdFile @@ -579,7 +582,7 @@ func (m *Manager) GetRemoteDigest(ctx context.Context, r *hub.Repository) (strin case GitRepoURLRE.MatchString(r.URL): // Do not track repo's digest for Tekton repos using git based versioning - if (r.Kind == hub.TektonTask || r.Kind == hub.TektonPipeline) && r.Data != nil { + if (r.Kind == hub.TektonTask || r.Kind == hub.TektonPipeline || r.Kind == hub.TektonStepAction) && r.Data != nil { var data *hub.TektonData if err := json.Unmarshal(r.Data, &data); err != nil { return "", fmt.Errorf("invalid tekton repository data: %w", err) @@ -844,7 +847,8 @@ func (m *Manager) validateURL(r *hub.Repository) error { hub.OPA, hub.TBAction, hub.TektonPipeline, - hub.TektonTask: + hub.TektonTask, + hub.TektonStepAction: if SchemeIsHTTP(u) && !GitRepoURLRE.MatchString(r.URL) { return errors.New("invalid url format") } diff --git a/internal/tracker/helpers.go b/internal/tracker/helpers.go index 2ea1cc05..c16a54d2 100644 --- a/internal/tracker/helpers.go +++ b/internal/tracker/helpers.go @@ -129,7 +129,7 @@ func SetupSource(i *hub.TrackerSourceInput) hub.TrackerSource { hub.OPA, hub.TBAction: source = generic.NewTrackerSource(i) - case hub.TektonTask, hub.TektonPipeline: + case hub.TektonTask, hub.TektonPipeline, hub.TektonStepAction: source = tekton.NewTrackerSource(i) } return source diff --git a/internal/tracker/source/tekton/tekton.go b/internal/tracker/source/tekton/tekton.go index b2959d3c..482508a5 100644 --- a/internal/tracker/source/tekton/tekton.go +++ b/internal/tracker/source/tekton/tekton.go @@ -22,6 +22,7 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/hashicorp/go-multierror" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + v1alpha "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" pipelinerun "github.com/tektoncd/pipeline/pkg/reconciler/pipelinerun/resources" taskrun "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" "sigs.k8s.io/yaml" @@ -278,7 +279,7 @@ func (s *TrackerSource) warn(err error) { } // GetManifest reads, parses and validates the package manifest, which can be a -// Tekton task or a pipeline manifest. +// Tekton task, pipeline or stepaction manifest. func GetManifest(kind hub.RepositoryKind, pkgName, pkgPath string) (interface{}, []byte, error) { manifestPath := path.Join(pkgPath, pkgName+".yaml") manifestData, err := os.ReadFile(manifestPath) @@ -291,6 +292,8 @@ func GetManifest(kind hub.RepositoryKind, pkgName, pkgPath string) (interface{}, manifest = &v1.Task{} case hub.TektonPipeline: manifest = &v1.Pipeline{} + case hub.TektonStepAction: + manifest = &v1alpha.StepAction{} } if err := yaml.Unmarshal(manifestData, &manifest); err != nil { return nil, nil, err @@ -316,6 +319,10 @@ func validateManifest(manifest interface{}) error { name = m.Name version = m.Labels[versionLabelTKey] description = m.Spec.Description + case *v1alpha.StepAction: + name = m.Name + version = m.Labels[versionLabelTKey] + description = "Tekton StepAction" // TODO: description missing in v1alpha.StepAction } // Validate manifest data @@ -335,7 +342,7 @@ func validateManifest(manifest interface{}) error { } // PreparePackageInput represents the information required to prepare a package -// of Tekton task and pipelines kinds. +// of Tekton task, pipeline and stepaction kinds. type PreparePackageInput struct { R *hub.Repository Tag string @@ -388,6 +395,16 @@ func PreparePackage(i *PreparePackageInput) (*hub.Package, error) { "run_after": mts.RunAfter, }) } + case *v1alpha.StepAction: + tektonKind = "stepaction" + name = m.Name + version = m.Labels[versionLabelTKey] + descriptionPrefix := m.Annotations[displayNameTKey] + if descriptionPrefix == "" { + descriptionPrefix = name + } + description = fmt.Sprintf("%s StepAction", descriptionPrefix) + annotations = m.Annotations } // Prepare version diff --git a/internal/tracker/source/tekton/tekton_test.go b/internal/tracker/source/tekton/tekton_test.go index f45af4ad..bd78a699 100644 --- a/internal/tracker/source/tekton/tekton_test.go +++ b/internal/tracker/source/tekton/tekton_test.go @@ -271,4 +271,97 @@ func TestTrackerSource(t *testing.T) { assert.NoError(t, err) sw.AssertExpectations(t) }) + + t.Run("one package returned (tekton-stepaction), no errors", func(t *testing.T) { + t.Parallel() + + // Setup services and expectations + sw := source.NewTestsServicesWrapper() + i := &hub.TrackerSourceInput{ + Repository: &hub.Repository{ + Kind: hub.TektonStepAction, + URL: "https://github.com/user/repo/path", + Data: json.RawMessage(fmt.Sprintf(`{"versioning": "%s"}`, hub.TektonDirBasedVersioning)), + }, + BasePath: "testdata/path5", + Svc: sw.Svc, + } + + // Run test and check expectations + manifestRaw, _ := os.ReadFile("testdata/path5/stepaction1/0.1/stepaction1.yaml") + var tasks []map[string]interface{} + p := &hub.Package{ + Name: "stepaction1", + DisplayName: "StepAction 1", + Description: "StepAction 1 StepAction", + Keywords: []string{"tekton", "stepaction", "tag1", "tag2"}, + Readme: "This is just a test stepaction\n", + Version: "0.1.0", + Provider: "Some organization", + ContentURL: "https://github.com/user/repo/raw/master/path/stepaction1/0.1/stepaction1.yaml", + Digest: "530682380f55de185372b1f2c776c0ef82b75273e33f9af34fa0279a9fb8ee0f", + Repository: i.Repository, + License: "Apache-2.0", + Links: []*hub.Link{ + { + Name: "source", + URL: "https://github.com/user/repo/blob/master/path/stepaction1/0.1/stepaction1.yaml", + }, + { + Name: "link1", + URL: "https://link1.url", + }, + { + Name: "link2", + URL: "https://link2.url", + }, + }, + Maintainers: []*hub.Maintainer{ + { + Name: "user1", + Email: "user1@email.com", + }, + { + Name: "user2", + Email: "user2@email.com", + }, + }, + Changes: []*hub.Change{ + { + Description: "Added cool feature", + }, + { + Description: "Fixed minor bug", + }, + }, + Recommendations: []*hub.Recommendation{ + { + URL: "https://artifacthub.io/packages/helm/artifact-hub/artifact-hub", + }, + }, + Screenshots: []*hub.Screenshot{ + { + Title: "Screenshot 1", + URL: "https://artifacthub.io/screenshot1.jpg", + }, + }, + Data: map[string]interface{}{ + PipelinesMinVersionKey: "0.54.0", + RawManifestKey: string(manifestRaw), + TasksKey: tasks, + PlatformsKey: []string{"linux/amd64", "linux/arm64"}, + ExamplesKey: map[string]string{ + "sample1.yaml": "sample content\n", + }, + }, + Signatures: []string{tekton}, + Signed: true, + } + packages, err := NewTrackerSource(i).GetPackagesAvailable() + assert.Equal(t, map[string]*hub.Package{ + pkg.BuildKey(p): p, + }, packages) + assert.NoError(t, err) + sw.AssertExpectations(t) + }) } diff --git a/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/README.md b/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/README.md new file mode 100644 index 00000000..6f15f832 --- /dev/null +++ b/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/README.md @@ -0,0 +1 @@ +This is just a test stepaction diff --git a/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/samples/sample1.yaml b/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/samples/sample1.yaml new file mode 100644 index 00000000..4b4f223d --- /dev/null +++ b/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/samples/sample1.yaml @@ -0,0 +1 @@ +sample content diff --git a/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/stepaction1.yaml b/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/stepaction1.yaml new file mode 100644 index 00000000..dc200ba2 --- /dev/null +++ b/internal/tracker/source/tekton/testdata/path5/stepaction1/0.1/stepaction1.yaml @@ -0,0 +1,37 @@ +apiVersion: tekton.dev/v1alpha1 +kind: StepAction +metadata: + name: stepaction1 + labels: + app.kubernetes.io/version: "0.1.0" + annotations: + artifacthub.io/changes: | + - Added cool feature + - Fixed minor bug + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: link1 + url: https://link1.url + - name: link2 + url: https://link2.url + artifacthub.io/maintainers: | + - name: user1 + email: user1@email.com + - name: user2 + email: user2@email.com + artifacthub.io/provider: Some organization + artifacthub.io/recommendations: | + - url: https://artifacthub.io/packages/helm/artifact-hub/artifact-hub + artifacthub.io/screenshots: | + - title: Screenshot 1 + url: https://artifacthub.io/screenshot1.jpg + tekton.dev/pipelines.minVersion: "0.54.0" + tekton.dev/platforms: "linux/amd64,linux/arm64" + tekton.dev/tags: tag1, tag2 + tekton.dev/displayName: "StepAction 1" + tekton.dev/signature: "stepaction signature val" +spec: + description: Test stepaction + params: + - name: param1 + description: param1 description diff --git a/internal/tracker/tracker.go b/internal/tracker/tracker.go index 68a17b09..91279fbd 100644 --- a/internal/tracker/tracker.go +++ b/internal/tracker/tracker.go @@ -203,7 +203,8 @@ func (t *Tracker) cloneRepository() (string, string, error) { hub.OPA, hub.TBAction, hub.TektonPipeline, - hub.TektonTask: + hub.TektonTask, + hub.TektonStepAction: tmpDir, packagesPath, err = t.svc.Rc.CloneRepository(t.svc.Ctx, t.r) } diff --git a/scripts/prepare-docs.sh b/scripts/prepare-docs.sh index 524e7a70..7dff928f 100755 --- a/scripts/prepare-docs.sh +++ b/scripts/prepare-docs.sh @@ -28,6 +28,7 @@ cat docs/www/headers/olm_operators_repositories docs/olm_operators_repositories. cat docs/www/headers/opa_policies_repositories docs/opa_policies_repositories.md > docs/www/content/topics/repositories/opa-policies.md cat docs/www/headers/tekton_pipelines_repositories docs/tekton_pipelines_repositories.md > docs/www/content/topics/repositories/tekton-pipelines.md cat docs/www/headers/tekton_tasks_repositories docs/tekton_tasks_repositories.md > docs/www/content/topics/repositories/tekton-tasks.md +cat docs/www/headers/tekton_stepactions_repositories docs/tekton_stepactions_repositories.md > docs/www/content/topics/repositories/tekton-stepactions.md cat docs/www/headers/tinkerbell_actions_repositories docs/tinkerbell_actions_repositories.md > docs/www/content/topics/repositories/tinkerbell-actions.md cat docs/www/headers/security_report docs/security_report.md > docs/www/content/topics/security_report.md cat docs/www/headers/cli docs/cli.md > docs/www/content/topics/cli.md diff --git a/web/src/layout/common/Image.tsx b/web/src/layout/common/Image.tsx index 794b084b..1d9de494 100644 --- a/web/src/layout/common/Image.tsx +++ b/web/src/layout/common/Image.tsx @@ -45,6 +45,7 @@ const Image = (props: Props) => { return '/static/media/placeholder_pkg_krew.png'; case RepositoryKind.TektonTask: case RepositoryKind.TektonPipeline: + case RepositoryKind.TektonStepAction: return '/static/media/placeholder_pkg_tekton-task.png'; case RepositoryKind.KedaScaler: return '/static/media/placeholder_pkg_keda-scaler.png'; diff --git a/web/src/layout/common/RepositoryIcon.test.tsx b/web/src/layout/common/RepositoryIcon.test.tsx index 4da459bf..cba03bbf 100644 --- a/web/src/layout/common/RepositoryIcon.test.tsx +++ b/web/src/layout/common/RepositoryIcon.test.tsx @@ -142,6 +142,13 @@ describe('RepositoryIcon', () => { expect(icon).toHaveProperty('src', 'http://localhost/static/media/inspektor-gadget-light.svg'); }); + it('renders Tekton StepAction icon', () => { + render(); + const icon = screen.getByAltText('Icon'); + expect(icon).toBeInTheDocument(); + expect(icon).toHaveProperty('src', 'http://localhost/static/media/tekton-pkg-light.svg'); + }); + it('renders empty icon', () => { render(); expect(() => screen.getByAltText('Icon')).toThrow(); diff --git a/web/src/layout/common/RepositoryIcon.tsx b/web/src/layout/common/RepositoryIcon.tsx index 061bd436..7f6bebc5 100644 --- a/web/src/layout/common/RepositoryIcon.tsx +++ b/web/src/layout/common/RepositoryIcon.tsx @@ -101,6 +101,10 @@ const ICONS = { default: '/static/media/inspektor-gadget.svg', white: '/static/media/inspektor-gadget-light.svg', }, + [RepositoryKind.TektonStepAction]: { + default: '/static/media/tekton-pkg.svg', + white: '/static/media/tekton-pkg-light.svg', + }, }; const RepositoryIcon = (props: Props) => { diff --git a/web/src/layout/common/badges/Signed.tsx b/web/src/layout/common/badges/Signed.tsx index 3bb1dae2..acf10943 100644 --- a/web/src/layout/common/badges/Signed.tsx +++ b/web/src/layout/common/badges/Signed.tsx @@ -30,6 +30,7 @@ const Signed = (props: Props) => { RepositoryKind.Kubewarden, RepositoryKind.TektonPipeline, RepositoryKind.TektonTask, + RepositoryKind.TektonStepAction, ].includes(props.repoKind); return ( diff --git a/web/src/layout/controlPanel/repositories/Modal.tsx b/web/src/layout/controlPanel/repositories/Modal.tsx index 4bf4eba8..df29fe25 100644 --- a/web/src/layout/controlPanel/repositories/Modal.tsx +++ b/web/src/layout/controlPanel/repositories/Modal.tsx @@ -191,7 +191,11 @@ const RepositoryModal = (props: Props) => { }; } - if ([RepositoryKind.TektonTask, RepositoryKind.TektonPipeline].includes(selectedKind)) { + if ( + [RepositoryKind.TektonTask, RepositoryKind.TektonPipeline, RepositoryKind.TektonStepAction].includes( + selectedKind + ) + ) { repository.data = { versioning: versioning, }; @@ -497,6 +501,17 @@ const RepositoryModal = (props: Props) => { ); break; + case RepositoryKind.TektonStepAction: + link = ( + + Tekton stepactions + + ); + break; } if (isUndefined(link)) return; @@ -527,6 +542,7 @@ const RepositoryModal = (props: Props) => { case RepositoryKind.KCL: case RepositoryKind.Headlamp: case RepositoryKind.InspektorGadget: + case RepositoryKind.TektonStepAction: return ( <>

{ RepositoryKind.KCL, RepositoryKind.Headlamp, RepositoryKind.InspektorGadget, + RepositoryKind.TektonStepAction, ].includes(selectedKind) && (

{
)} - {[RepositoryKind.TektonTask, RepositoryKind.TektonPipeline].includes(selectedKind) && ( + {[RepositoryKind.TektonTask, RepositoryKind.TektonPipeline, RepositoryKind.TektonStepAction].includes( + selectedKind + ) && ( <> @@ -1068,6 +1087,7 @@ const RepositoryModal = (props: Props) => { RepositoryKind.KCL, RepositoryKind.Headlamp, RepositoryKind.InspektorGadget, + RepositoryKind.TektonStepAction, ].includes(selectedKind) && (
diff --git a/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap b/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap index c3e900ac..07aa68f2 100644 --- a/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap +++ b/web/src/layout/controlPanel/repositories/__snapshots__/Modal.test.tsx.snap @@ -164,6 +164,11 @@ exports[`Repository Modal - repositories section creates snapshot 1`] = ` > Tekton pipelines +