Skip to content

feat: add OCI artifact support for testworkflows - #6767

Open
dhimanAbhi wants to merge 3 commits into
kubeshop:mainfrom
dhimanAbhi:feat/oci-support-testworkflow
Open

dhimanAbhi wants to merge 3 commits into
kubeshop:mainfrom
dhimanAbhi:feat/oci-support-testworkflow

Conversation

@dhimanAbhi

@dhimanAbhi dhimanAbhi commented Oct 18, 2025 •

Copy link
Copy Markdown
Contributor

Pull request description

This PR introduces support for OCI registry sources in the container executor. It enables fetching test assets directly from OCI-compliant registries (such as Docker Hub, GHCR, or self-hosted registries) as an alternative to Git-based sources. This addition provides a secure and reliable way to distribute test content, especially for air-gapped or restricted network environments, here access to public Git repositories may not be feasible.

It solves issue #4849

Proof Manifests

These are logs of testworkflow execution where I had pushed cypress test defined in testkube/test/cypress/cypress-12 to my dockerhub private repo as an artifact using ORAS. This PR fetches the content just like fetching from Git Source.

$ testkube watch twe 68f37d47a1ceb4408c389b79

Context:  (999.0.0-5d710d124)   Namespace: testkube
---------------------------------------------------
parsing server version 'dev': Invalid Semantic Version
Test Workflow Execution:
Name:                 oci-test
Execution ID:         68f37d47a1ceb4408c389b79
Execution name:       oci-test-1
Execution namespace:
Execution number:     1
Requested at:         2025-10-18 11:43:03.454 +0000 UTC
Disabled webhooks:    false
Status:               running
Queued at:            2025-10-18 11:43:03.454 +0000 UTC
Started at:           2025-10-18 11:43:03.454 +0000 UTC

Getting logs from test workflow job 68f37d47a1ceb4408c389b79
(SuccessfulCreate) Created pod: 68f37d47a1ceb4408c389b79-h27ns
(Scheduled) Successfully assigned testkube/68f37d47a1ceb4408c389b79-h27ns to minikube
(Pulled) Container image "docker.io/testworkflow-toolkit:oci" already present on machine
Creating state... done
Initializing state... done
Configuring init process... skipped
Configuring toolkit... done
Configuring shell... skipped

• passed in 2.613s

• (1/2) Get OCI artifact
Starting OCI fetch for artifact: abhi2002dhiman/cypress-test-artifact:latest to path: /data/repo
Downloading and extracting artifact...
✅ OCI artifact fetched successfully.
Moving artifact contents to /data/repo...
📥 Moving the contents to /data/repo...
📥 Adjusting access permissions...
🔎 Destination folder contains following files ...
/data/repo
/data/repo/.gitignore
/data/repo/Dockerfile
/data/repo/cypress
/data/repo/cypress/e2e
/data/repo/cypress/e2e/smoke.cy.js
/data/repo/cypress/e2e/smoke2.cy.js
/data/repo/cypress/fixtures
/data/repo/cypress/fixtures/.gitkeep
/data/repo/cypress/support
/data/repo/cypress/support/.gitkeep
/data/repo/cypress/support/e2e.js
/data/repo/cypress.config.js
/data/repo/package-lock.json
/data/repo/package.json
✅ Successfully fetched OCI artifact: abhi2002dhiman/cypress-test-artifact:latest

• passed in 2.603s
(Pulled) Container image "docker.io/testworkflow-toolkit:oci" already present on machine

• (2/2) Run shell command
/data/repo
├── Dockerfile
├── cypress
│   ├── e2e
│   │   ├── smoke.cy.js
│   │   └── smoke2.cy.js
│   ├── fixtures
│   └── support
│       └── e2e.js
├── cypress.config.js
├── package-lock.json
└── package.json2025-10-18T11:43:09.086320526Z 4 directories, 7 files

Testworkflow Definition

Users can define an OCI registry source specifying:

  • registry — where the artifact is hosted
  • image — artifact name and tag
  • path — path within the artifact to the test directory
  • username and token — optional, for private registries

Template -

apiVersion: testworkflows.testkube.io/v1
kind: TestWorkflow
metadata:
  name: oci-example
spec:
  content:
    oci:
      registry: "<registry_name>"
      image: "<artifact_name_with_tag>"
      path: "<path_to_test>"
      username: "<username>"
      token: "<token_or_password>"
  steps:
    - shell: "tree /data/repo"

Example

apiVersion: testworkflows.testkube.io/v1
kind: TestWorkflow
metadata:
  name: oci-example
spec:
  content:
    oci:
      registry: "docker.io"
      image: "abhi2002dhiman/cypress-test-artifact:latest"
      path: "."
      username: "abhi2002dhiman"
      token: "my_token"
  steps:
    - shell: "tree /data/repo"

Checklist (choose whats happened)

  • breaking change! (describe)
  • tested locally
  • tested on cluster
  • added new dependencies
  • updated the docs
  • added a test

Breaking changes

Changes

Fixes

@dhimanAbhi
dhimanAbhi requested a review from a team as a code owner October 18, 2025 13:26
@vsukhin

vsukhin commented Oct 20, 2025

Copy link
Copy Markdown
Collaborator

hey, @dhimanAbhi thank you for your contribution. Looks like a good work, but there is no api spec changes there, that is sued to generate models

@vsukhin vsukhin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add api spec changes used for mode generation

@vsukhin

vsukhin commented Oct 21, 2025

Copy link
Copy Markdown
Collaborator

@dhimanAbhi

Copy link
Copy Markdown
Contributor Author

Thanks @vsukhin , I updated api spec and some minor improvements. Let me know if you have any other thoughts or suggestions for further changes!

@vsukhin

vsukhin commented Oct 22, 2025

Copy link
Copy Markdown
Collaborator

I have one questions,are CRD installed without kubectl apply --server-side having thier size was increased?

@vsukhin

vsukhin commented Oct 22, 2025

Copy link
Copy Markdown
Collaborator

Also, don't you mind to prepare PR for https://github.com/kubeshop/testkube-docs with updated Content spec?

@dhimanAbhi

Copy link
Copy Markdown
Contributor Author

I have one questions,are CRD installed without kubectl apply --server-side having thier size was increased?

@vsukhin , I generated CRDs and api spec using Makefile commands make generate-openapi and and make generate-crds . If there’s another recommended way to generate CRDs, please let me know, I’ll update it right away!

@dhimanAbhi

Copy link
Copy Markdown
Contributor Author

Also, don't you mind to prepare PR for https://github.com/kubeshop/testkube-docs with updated Content spec?

Definetly. I will soon make a PR for the documentation update.

@vsukhin

vsukhin commented Oct 22, 2025

Copy link
Copy Markdown
Collaborator

I have one questions,are CRD installed without kubectl apply --server-side having thier size was increased?

@vsukhin , I generated CRDs and api spec using Makefile commands make generate-openapi and and make generate-crds . If there’s another recommended way to generate CRDs, please let me know, I’ll update it right away!

It's fine. It's just about testing, because for large CRDs we can have a warning from Kubernetes about thier size

@dhimanAbhi

Copy link
Copy Markdown
Contributor Author

I have one questions,are CRD installed without kubectl apply --server-side having thier size was increased?

@vsukhin , I generated CRDs and api spec using Makefile commands make generate-openapi and and make generate-crds . If there’s another recommended way to generate CRDs, please let me know, I’ll update it right away!

It's fine. It's just about testing, because for large CRDs we can have a warning from Kubernetes about thier size

Sounds Great. Let me know if anything else is required from my end! 🙌

@olensmar olensmar added the 👽 external-contribution External contribution label Jan 17, 2026
@vsukhin

vsukhin commented Feb 20, 2026

Copy link
Copy Markdown
Collaborator

@greptile

@greptile-apps

greptile-apps Bot commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds OCI (Open Container Initiative) registry support as a new content source for TestWorkflows, enabling users to fetch test artifacts from OCI-compliant registries like Docker Hub, GHCR, or private registries. This is particularly valuable for air-gapped environments where Git access may be restricted.

Key Changes

  • Implemented new /toolkit oci command using the regclient library for fetching OCI artifacts
  • Added ContentOci type with support for image reference, registry, authentication credentials (username/token), and path extraction
  • Refactored shared utility functions (copyDirContents, adjustFilePermissions, listDirectoryContents) from clone.go into utils.go for reuse
  • Integrated OCI processing into the workflow processor pipeline with ProcessContentOci()
  • Updated CRDs, OpenAPI specs, and type mappers to support the new content source

Issues Found

  • Critical bug in pkg/mapper/testworkflows/openapi_kube.go: The Path field is missing from MapContentOciAPIToKube(), which will cause API requests specifying a path within the artifact to lose that parameter when converted to Kubernetes types

Missing Test Coverage

  • No unit tests for the new oci.go command (compare with clone.go which has clone_test.go)
  • No integration tests demonstrating OCI artifact fetching

Security Considerations

  • Credentials are properly handled through both inline strings and external references (UsernameFrom, TokenFrom)
  • Authentication configuration follows existing patterns from Git content source
  • The implementation uses the well-established regclient library (v0.9.2)

Confidence Score: 3/5

  • This PR has one critical bug that must be fixed before merging, and lacks test coverage for the new OCI functionality
  • The implementation is well-structured and follows existing patterns, but the missing Path field in the API-to-Kube mapper will cause runtime issues where users specify a path parameter. Additionally, the absence of any unit tests for the new OCI command is concerning given that similar commands (like clone) have comprehensive test coverage
  • Pay close attention to pkg/mapper/testworkflows/openapi_kube.go (missing field bug) and consider adding test coverage for cmd/testworkflow-toolkit/commands/oci.go

Important Files Changed

Filename Overview
cmd/testworkflow-toolkit/commands/oci.go New OCI artifact fetching command implementation using regclient library - clean implementation with proper error handling
cmd/testworkflow-toolkit/commands/utils.go Refactored shared utility functions for file operations - extracted from clone.go for reuse in OCI command
pkg/mapper/testworkflows/openapi_kube.go Mapper for OCI content from OpenAPI to Kube types - missing Path field causes data loss
pkg/mapper/testworkflows/kube_openapi.go Mapper for OCI content from Kube to OpenAPI types - correctly includes all fields
api/testworkflows/v1/content_types.go Added ContentOci struct definition with proper field tags and support for external credentials
pkg/testworkflows/testworkflowprocessor/operations.go Added ProcessContentOci operation handler - follows existing patterns for Git and Tarball content sources

Sequence Diagram

sequenceDiagram
    participant User
    participant API
    participant Processor
    participant K8s
    participant Toolkit
    participant Registry

    User->>API: Submit TestWorkflow with content.oci
    API->>Processor: Process workflow spec
    Processor->>Processor: ProcessContentOci()
    Processor->>K8s: Create Job with toolkit container
    K8s->>Toolkit: Execute /toolkit oci command
    Toolkit->>Registry: Authenticate (username/token)
    Registry-->>Toolkit: Auth successful
    Toolkit->>Registry: Fetch manifest & layers
    Registry-->>Toolkit: Return artifact layers
    Toolkit->>Toolkit: Extract layers to temp directory
    Toolkit->>Toolkit: Copy content from path to mountPath
    Toolkit->>Toolkit: Adjust file permissions
    Toolkit-->>K8s: Artifact fetched to volume
    K8s->>K8s: Execute test steps with artifact content
Loading

Last reviewed commit: f8a4362

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment thread pkg/mapper/testworkflows/openapi_kube.go

@vsukhin vsukhin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @dhimanAbhi one more great contribution! please my and greptile. did you test it well in kubernetes cluster?

@@ -671,6 +671,174 @@ spec:
x-kubernetes-map-type: atomic
type: object
type: object

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you test CRD size? Any warnings from Kubernetes

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these changes in helm/testkube-operator?

@vsukhin

vsukhin commented Feb 20, 2026

Copy link
Copy Markdown
Collaborator

@dhimanAbhi also back merge main branch

@olensmar

olensmar commented Mar 3, 2026

Copy link
Copy Markdown
Member

@dhimanAbhi please let us know if you plan to update

@dhimanAbhi

Copy link
Copy Markdown
Contributor Author

Hi @olensmar, yes, I’ll be fixing the issues mentioned above. I’ll push an update by the end of this week.

Signed-off-by: Abhishek Dhiman <abhi2002dhiman@gmail.com>
Signed-off-by: Abhishek Dhiman <abhi2002dhiman@gmail.com>
Signed-off-by: Abhishek Dhiman <abhi2002dhiman@gmail.com>
@dhimanAbhi
dhimanAbhi force-pushed the feat/oci-support-testworkflow branch from f8a4362 to f3869d9 Compare March 9, 2026 11:23
@dhimanAbhi

Copy link
Copy Markdown
Contributor Author

Thanks for the review @vsukhin !

I tested the changes in a local kind cluster by building the Testkube images and applying the updated CRDs from k8s/crd. The CRDs were accepted by Kubernetes without any warnings, and the OCI-based TestWorkflow configuration worked as expected.

I also regenerated and synchronized the corresponding Helm CRDs, so the updated definitions are now reflected in k8s/helm/testkube-operator/templates as well.

Please let me know if there’s anything else I should verify or improve.

@vsukhin

vsukhin commented Mar 19, 2026

Copy link
Copy Markdown
Collaborator

thank you @dhimanAbhi let me recheck it

@vsukhin

vsukhin commented Mar 19, 2026

Copy link
Copy Markdown
Collaborator

@greptile are these CRD changes will not be over CRD size used on client side?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

👽 external-contribution External contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants