diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..5e12b9be --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,63 @@ +name: Bug 🐞 +description: Report a bug report +type: bug + +body: + - type: markdown + attributes: + value: | + Before opening a bug report, please search for the behaviour in the existing issues. + + --- + + Thank you for taking the time to file a bug report. To address this bug as fast as possible, we need some information. + + - type: textarea + id: bug-description + attributes: + label: Bug description + description: What happened? + validations: + required: true + + - type: input + id: user-agent + attributes: + label: user agent + description: 'Which operating system are you on? Please provide the version as well. If you are on a Mac, please specify Apple silicon or Intel.' + placeholder: 'macOS Ventura 13.4 (Arm), Windows 11' + validations: + required: true + + - type: dropdown + id: install + attributes: + label: Installation Method + description: 'How did you install Podman Desktop?' + options: + - 'Installer from website/GitHub releases' + - 'Brew (macOS)' + - 'Chocolatey (Windows)' + - 'Flathub (Linux)' + - 'Scoop (Windows)' + - 'Winget (Windows)' + - 'Other' + + - type: textarea + id: environment + attributes: + label: which environment + description: What steps do we need to take to reproduce this error? + + - type: textarea + id: image-proxy + attributes: + label: image of proxy + description: If applicable, provide relevant log output. + render: shell + + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Add any other context or screenshots here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..df518d5f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,41 @@ +name: Feature 🐞 +description: Request a feature +type: feature + +body: + - type: markdown + attributes: + value: | + Before opening a feature request, please search for the behaviour in the existing issues. + + --- + + Thank you for taking the time to file a bug report. To address this bug as fast as possible, we need some information. + + - type: textarea + id: feature-description + attributes: + label: Feature description + description: What happened? + validations: + required: true + + - type: dropdown + id: install + attributes: + label: Installation Method + description: 'How did you install Podman Desktop?' + options: + - 'Installer from website/GitHub releases' + - 'Brew (macOS)' + - 'Chocolatey (Windows)' + - 'Flathub (Linux)' + - 'Scoop (Windows)' + - 'Winget (Windows)' + - 'Other' + + - type: textarea + id: additional-context + attributes: + label: Additional context + description: Add any other context or screenshots here. diff --git a/.tekton/cara-konflux-ui-test-b1228-pull-request.yaml b/.tekton/cara-konflux-ui-test-b1228-pull-request.yaml new file mode 100644 index 00000000..b644df07 --- /dev/null +++ b/.tekton/cara-konflux-ui-test-b1228-pull-request.yaml @@ -0,0 +1,583 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + annotations: + build.appstudio.openshift.io/repo: https://github.com/testcara/konflux-ui-test?rev={{revision}} + build.appstudio.redhat.com/commit_sha: '{{revision}}' + build.appstudio.redhat.com/pull_request_number: '{{pull_request_number}}' + build.appstudio.redhat.com/target_branch: '{{target_branch}}' + pipelinesascode.tekton.dev/cancel-in-progress: "true" + pipelinesascode.tekton.dev/max-keep-runs: "3" + pipelinesascode.tekton.dev/on-cel-expression: event == "pull_request" && target_branch + == "main" + creationTimestamp: null + labels: + appstudio.openshift.io/application: konflux-ui-test + appstudio.openshift.io/component: cara-konflux-ui-test-b1228 + pipelines.appstudio.openshift.io/type: build + name: cara-konflux-ui-test-b1228-on-pull-request + namespace: wlin-tenant +spec: + params: + - name: git-url + value: '{{source_url}}' + - name: revision + value: '{{revision}}' + - name: output-image + value: quay.io/redhat-user-workloads-stage/wlin-tenant/cara-konflux-ui-test-b1228:on-pr-{{revision}} + - name: image-expires-after + value: 5d + - name: dockerfile + value: Dockerfile + pipelineSpec: + description: | + This pipeline is ideal for building container images from a Containerfile while maintaining trust after pipeline customization. + + _Uses `buildah` to create a container image leveraging [trusted artifacts](https://konflux-ci.dev/architecture/ADR/0036-trusted-artifacts.html). It also optionally creates a source image and runs some build-time tests. Information is shared between tasks using OCI artifacts instead of PVCs. EC will pass the [`trusted_task.trusted`](https://conforma.dev/docs/policy/packages/release_trusted_task.html#trusted_task__trusted) policy as long as all data used to build the artifact is generated from trusted tasks. + This pipeline is pushed as a Tekton bundle to [quay.io](https://quay.io/repository/konflux-ci/tekton-catalog/pipeline-docker-build-oci-ta?tab=tags)_ + params: + - description: Source Repository URL + name: git-url + type: string + - default: "" + description: Revision of the Source Repository + name: revision + type: string + - description: Fully Qualified Output Image + name: output-image + type: string + - default: . + description: Path to the source code of an application's component from where + to build image. + name: path-context + type: string + - default: Dockerfile + description: Path to the Dockerfile inside the context specified by parameter + path-context + name: dockerfile + type: string + - default: "false" + description: Skip checks against built image + name: skip-checks + type: string + - default: "false" + description: Execute the build with network isolation + name: hermetic + type: string + - default: "" + description: Build dependencies to be prefetched + name: prefetch-input + type: string + - default: "" + description: Image tag expiration time, time values could be something like + 1h, 2d, 3w for hours, days, and weeks, respectively. + name: image-expires-after + type: string + - default: "false" + description: Build a source image. + name: build-source-image + type: string + - default: "false" + description: Add built image into an OCI image index + name: build-image-index + type: string + - default: docker + description: The format for the resulting image's mediaType. Valid values are + oci or docker. + name: buildah-format + type: string + - default: "false" + description: Enable cache proxy configuration + name: enable-cache-proxy + - default: [] + description: Array of --build-arg values ("arg=value" strings) for buildah + name: build-args + type: array + - default: "" + description: Path to a file with build arguments for buildah, see https://www.mankier.com/1/buildah-build#--build-arg-file + name: build-args-file + type: string + - default: "false" + description: Whether to enable privileged mode, should be used only with remote + VMs + name: privileged-nested + type: string + results: + - description: "" + name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - description: "" + name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - description: "" + name: CHAINS-GIT_URL + value: $(tasks.clone-repository.results.url) + - description: "" + name: CHAINS-GIT_COMMIT + value: $(tasks.clone-repository.results.commit) + tasks: + - name: init + params: + - name: enable-cache-proxy + value: $(params.enable-cache-proxy) + taskRef: + params: + - name: name + value: init + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-init:0.4@sha256:288f3106118edc1d0f0c79a89c960abf5841a4dd8bc3f38feb10527253105b19 + - name: kind + value: task + resolver: bundles + - name: clone-repository + params: + - name: url + value: $(params.git-url) + - name: revision + value: $(params.revision) + - name: ociStorage + value: $(params.output-image).git + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - init + taskRef: + params: + - name: name + value: git-clone-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:2c388d28651457db60bb90287e7d8c3680303197196e4476878d98d81e8b6dc9 + - name: kind + value: task + resolver: bundles + workspaces: + - name: basic-auth + workspace: git-auth + - name: prefetch-dependencies + params: + - name: input + value: $(params.prefetch-input) + - name: SOURCE_ARTIFACT + value: $(tasks.clone-repository.results.SOURCE_ARTIFACT) + - name: ociStorage + value: $(params.output-image).prefetch + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - clone-repository + taskRef: + params: + - name: name + value: prefetch-dependencies-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:22612d629796a29ddd177d6e29c18a4319875d4e2348286ea01d16427cec0dc1 + - name: kind + value: task + resolver: bundles + workspaces: + - name: git-basic-auth + workspace: git-auth + - name: netrc + workspace: netrc + - name: build-container + params: + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: PRIVILEGED_NESTED + value: $(params.privileged-nested) + - name: SOURCE_URL + value: $(tasks.clone-repository.results.url) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + - name: HTTP_PROXY + value: $(tasks.init.results.http-proxy) + - name: NO_PROXY + value: $(tasks.init.results.no-proxy) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - prefetch-dependencies + taskRef: + params: + - name: name + value: buildah-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-buildah-oci-ta:0.9@sha256:8db8c8fe3dcbf75a7ae2e55691d9b68823e106ebe302ef89556e8b71484c3725 + - name: kind + value: task + resolver: bundles + - name: build-image-index + params: + - name: IMAGE + value: $(params.output-image) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: ALWAYS_BUILD_INDEX + value: $(params.build-image-index) + - name: IMAGES + value: + - $(tasks.build-container.results.IMAGE_URL)@$(tasks.build-container.results.IMAGE_DIGEST) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + runAfter: + - build-container + taskRef: + params: + - name: name + value: build-image-index + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:ac4f8b58ade5000f6e47d287b72832f0d89a91651849467be73e05da639cff7d + - name: kind + value: task + resolver: bundles + - name: build-source-image + params: + - name: BINARY_IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: BINARY_IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: source-build-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:eb620d137d2dfa9966d991ac210ad14f391cfa9cfc501e3cc1eb24e3332c6986 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.build-source-image) + operator: in + values: + - "true" + - name: deprecated-base-image-check + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: deprecated-image-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clair-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clair-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:654b989d7cdc03d082e56f216a29de04847215ee379a8d9ca315e453ad2b15c2 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: ecosystem-cert-preflight-checks + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: ecosystem-cert-preflight-checks + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:945f8ba72381402ce6b00efa24a6eeb19a27ba68b445474c28ebfbfb21bb365f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-snyk-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-snyk-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:49b7d09db82e6cad98152db8f16707ca3d90a1709e846e3ed8c91a433c88724f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clamav-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clamav-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:b2f25599a10ab0846e4659f76b5b78c0fddf561404656fda52055eda31e70d83 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-coverity-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - coverity-availability-check + taskRef: + params: + - name: name + value: sast-coverity-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-coverity-check-oci-ta:0.3@sha256:9978b6163d54473a72ded5eb9b75d9ffae92118e544c7b96dc805cd66870b12d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - input: $(tasks.coverity-availability-check.results.STATUS) + operator: in + values: + - success + - name: coverity-availability-check + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: coverity-availability-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-coverity-availability-check:0.2@sha256:267d5bc069a0323f41e24732ddfd1057e5c639e853d1e620c67505fab78f1301 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-shell-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-shell-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:e7a51575f9188a1461d4520da25aaa4efdd3b896c97dc750941fa22840e55c13 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-unicode-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-unicode-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:0ca0203c25e22c9f12cc32436f6bf02df19fd177ba5f84926d804c711146974e + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: apply-tags + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: apply-tags + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:510b6d2a3b188adeb716e49566b57d611ab36bd69a2794b5ddfc11dbf014c2ca + - name: kind + value: task + resolver: bundles + - name: push-dockerfile + params: + - name: IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: push-dockerfile-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.3@sha256:1bc2d0f26b89259db090a47bb38217c82c05e335d626653d184adf1d196ca131 + - name: kind + value: task + resolver: bundles + - name: rpms-signature-scan + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: rpms-signature-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:47b81d6b3d752649eddfbb8b3fd8f6522c4bb07f6d1946f9bc45dae3f92e2c9a + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + workspaces: + - name: git-auth + optional: true + - name: netrc + optional: true + taskRunTemplate: + serviceAccountName: build-pipeline-cara-konflux-ui-test-b1228 + workspaces: + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' +status: {} diff --git a/.tekton/cara-konflux-ui-test-b1228-push.yaml b/.tekton/cara-konflux-ui-test-b1228-push.yaml new file mode 100644 index 00000000..71e9eed9 --- /dev/null +++ b/.tekton/cara-konflux-ui-test-b1228-push.yaml @@ -0,0 +1,582 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + annotations: + build.appstudio.openshift.io/repo: https://github.com/testcara/konflux-ui-test?rev={{revision}} + build.appstudio.redhat.com/commit_sha: '{{revision}}' + build.appstudio.redhat.com/target_branch: '{{target_branch}}' + pipelinesascode.tekton.dev/cancel-in-progress: "false" + pipelinesascode.tekton.dev/max-keep-runs: "3" + pipelinesascode.tekton.dev/on-cel-expression: event == "push" && target_branch + == "main" + creationTimestamp: null + labels: + appstudio.openshift.io/application: konflux-ui-test + appstudio.openshift.io/component: cara-konflux-ui-test-b1228 + pipelines.appstudio.openshift.io/type: build + name: cara-konflux-ui-test-b1228-on-push + namespace: wlin-tenant +spec: + params: + - name: git-url + value: '{{source_url}}' + - name: revision + value: '{{revision}}' + - name: output-image + value: quay.io/redhat-user-workloads-stage/wlin-tenant/cara-konflux-ui-test-b1228:{{revision}} + - name: dockerfile + value: Dockerfile + - name: skip-checks + value: "true" + pipelineSpec: + description: | + This pipeline is ideal for building container images from a Containerfile while maintaining trust after pipeline customization. + + _Uses `buildah` to create a container image leveraging [trusted artifacts](https://konflux-ci.dev/architecture/ADR/0036-trusted-artifacts.html). It also optionally creates a source image and runs some build-time tests. Information is shared between tasks using OCI artifacts instead of PVCs. EC will pass the [`trusted_task.trusted`](https://conforma.dev/docs/policy/packages/release_trusted_task.html#trusted_task__trusted) policy as long as all data used to build the artifact is generated from trusted tasks. + This pipeline is pushed as a Tekton bundle to [quay.io](https://quay.io/repository/konflux-ci/tekton-catalog/pipeline-docker-build-oci-ta?tab=tags)_ + params: + - description: Source Repository URL + name: git-url + type: string + - default: "" + description: Revision of the Source Repository + name: revision + type: string + - description: Fully Qualified Output Image + name: output-image + type: string + - default: . + description: Path to the source code of an application's component from where + to build image. + name: path-context + type: string + - default: Dockerfile + description: Path to the Dockerfile inside the context specified by parameter + path-context + name: dockerfile + type: string + - default: "false" + description: Skip checks against built image + name: skip-checks + type: string + - default: "false" + description: Execute the build with network isolation + name: hermetic + type: string + - default: "" + description: Build dependencies to be prefetched + name: prefetch-input + type: string + - default: "" + description: Image tag expiration time, time values could be something like + 1h, 2d, 3w for hours, days, and weeks, respectively. + name: image-expires-after + type: string + - default: "false" + description: Build a source image. + name: build-source-image + type: string + - default: "false" + description: Add built image into an OCI image index + name: build-image-index + type: string + - default: docker + description: The format for the resulting image's mediaType. Valid values are + oci or docker. + name: buildah-format + type: string + - default: "false" + description: Enable cache proxy configuration + name: enable-cache-proxy + - default: [] + description: Array of --build-arg values ("arg=value" strings) for buildah + name: build-args + type: array + - default: "" + description: Path to a file with build arguments for buildah, see https://www.mankier.com/1/buildah-build#--build-arg-file + name: build-args-file + type: string + - default: "false" + description: Whether to enable privileged mode, should be used only with remote + VMs + name: privileged-nested + type: string + results: + - description: "" + name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - description: "" + name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - description: "" + name: CHAINS-GIT_URL + value: $(tasks.clone-repository.results.url) + - description: "" + name: CHAINS-GIT_COMMIT + value: $(tasks.clone-repository.results.commit) + tasks: + - name: init + params: + - name: enable-cache-proxy + value: $(params.enable-cache-proxy) + taskRef: + params: + - name: name + value: init + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-init:0.4@sha256:288f3106118edc1d0f0c79a89c960abf5841a4dd8bc3f38feb10527253105b19 + - name: kind + value: task + resolver: bundles + - name: clone-repository + params: + - name: url + value: $(params.git-url) + - name: revision + value: $(params.revision) + - name: ociStorage + value: $(params.output-image).git + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - init + taskRef: + params: + - name: name + value: git-clone-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:2c388d28651457db60bb90287e7d8c3680303197196e4476878d98d81e8b6dc9 + - name: kind + value: task + resolver: bundles + workspaces: + - name: basic-auth + workspace: git-auth + - name: prefetch-dependencies + params: + - name: input + value: $(params.prefetch-input) + - name: SOURCE_ARTIFACT + value: $(tasks.clone-repository.results.SOURCE_ARTIFACT) + - name: ociStorage + value: $(params.output-image).prefetch + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - clone-repository + taskRef: + params: + - name: name + value: prefetch-dependencies-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:22612d629796a29ddd177d6e29c18a4319875d4e2348286ea01d16427cec0dc1 + - name: kind + value: task + resolver: bundles + workspaces: + - name: git-basic-auth + workspace: git-auth + - name: netrc + workspace: netrc + - name: build-container + params: + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: PRIVILEGED_NESTED + value: $(params.privileged-nested) + - name: SOURCE_URL + value: $(tasks.clone-repository.results.url) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + - name: HTTP_PROXY + value: $(tasks.init.results.http-proxy) + - name: NO_PROXY + value: $(tasks.init.results.no-proxy) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - prefetch-dependencies + taskRef: + params: + - name: name + value: buildah-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-buildah-oci-ta:0.9@sha256:8db8c8fe3dcbf75a7ae2e55691d9b68823e106ebe302ef89556e8b71484c3725 + - name: kind + value: task + resolver: bundles + - name: build-image-index + params: + - name: IMAGE + value: $(params.output-image) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: ALWAYS_BUILD_INDEX + value: $(params.build-image-index) + - name: IMAGES + value: + - $(tasks.build-container.results.IMAGE_URL)@$(tasks.build-container.results.IMAGE_DIGEST) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + runAfter: + - build-container + taskRef: + params: + - name: name + value: build-image-index + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:ac4f8b58ade5000f6e47d287b72832f0d89a91651849467be73e05da639cff7d + - name: kind + value: task + resolver: bundles + - name: build-source-image + params: + - name: BINARY_IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: BINARY_IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: source-build-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:eb620d137d2dfa9966d991ac210ad14f391cfa9cfc501e3cc1eb24e3332c6986 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.build-source-image) + operator: in + values: + - "true" + - name: deprecated-base-image-check + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: deprecated-image-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clair-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clair-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:654b989d7cdc03d082e56f216a29de04847215ee379a8d9ca315e453ad2b15c2 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: ecosystem-cert-preflight-checks + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: ecosystem-cert-preflight-checks + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:945f8ba72381402ce6b00efa24a6eeb19a27ba68b445474c28ebfbfb21bb365f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-snyk-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-snyk-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:49b7d09db82e6cad98152db8f16707ca3d90a1709e846e3ed8c91a433c88724f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clamav-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clamav-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:b2f25599a10ab0846e4659f76b5b78c0fddf561404656fda52055eda31e70d83 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-coverity-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - coverity-availability-check + taskRef: + params: + - name: name + value: sast-coverity-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-coverity-check-oci-ta:0.3@sha256:9978b6163d54473a72ded5eb9b75d9ffae92118e544c7b96dc805cd66870b12d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - input: $(tasks.coverity-availability-check.results.STATUS) + operator: in + values: + - success + - name: coverity-availability-check + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: coverity-availability-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-coverity-availability-check:0.2@sha256:267d5bc069a0323f41e24732ddfd1057e5c639e853d1e620c67505fab78f1301 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-shell-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-shell-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:e7a51575f9188a1461d4520da25aaa4efdd3b896c97dc750941fa22840e55c13 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-unicode-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-unicode-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:0ca0203c25e22c9f12cc32436f6bf02df19fd177ba5f84926d804c711146974e + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: apply-tags + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: apply-tags + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:510b6d2a3b188adeb716e49566b57d611ab36bd69a2794b5ddfc11dbf014c2ca + - name: kind + value: task + resolver: bundles + - name: push-dockerfile + params: + - name: IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: push-dockerfile-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.3@sha256:1bc2d0f26b89259db090a47bb38217c82c05e335d626653d184adf1d196ca131 + - name: kind + value: task + resolver: bundles + - name: rpms-signature-scan + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: rpms-signature-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:47b81d6b3d752649eddfbb8b3fd8f6522c4bb07f6d1946f9bc45dae3f92e2c9a + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + workspaces: + - name: git-auth + optional: true + - name: netrc + optional: true + taskRunTemplate: + serviceAccountName: build-pipeline-cara-konflux-ui-test-b1228 + workspaces: + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' +status: {} diff --git a/.tekton/konflux-ui-pull-request.yaml b/.tekton/konflux-ui-pull-request.yaml index 0b26ed07..ed7172b4 100644 --- a/.tekton/konflux-ui-pull-request.yaml +++ b/.tekton/konflux-ui-pull-request.yaml @@ -10,11 +10,11 @@ metadata: pipelinesascode.tekton.dev/on-cel-expression: (event == "pull_request" && target_branch == "main" && ( !has(body.pull_request) || !body.pull_request.draft) ) || (event == "push" && target_branch.startsWith("gh-readonly-queue/main/") && body.head_commit != "null" ) creationTimestamp: labels: - appstudio.openshift.io/application: konflux-ui - appstudio.openshift.io/component: konflux-ui + appstudio.openshift.io/application: dummy-konflux + appstudio.openshift.io/component: konflux-ui-test pipelines.appstudio.openshift.io/type: build name: konflux-ui-on-pull-request - namespace: konflux-ui-tenant + namespace: abhindas-tenant spec: params: - name: git-url diff --git a/.tekton/konflux-ui-test-pull-request.yaml b/.tekton/konflux-ui-test-pull-request.yaml new file mode 100644 index 00000000..131ca19a --- /dev/null +++ b/.tekton/konflux-ui-test-pull-request.yaml @@ -0,0 +1,583 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + annotations: + build.appstudio.openshift.io/repo: https://github.com/abhinandan13jan/konflux-ui-test?rev={{revision}} + build.appstudio.redhat.com/commit_sha: '{{revision}}' + build.appstudio.redhat.com/pull_request_number: '{{pull_request_number}}' + build.appstudio.redhat.com/target_branch: '{{target_branch}}' + pipelinesascode.tekton.dev/cancel-in-progress: "true" + pipelinesascode.tekton.dev/max-keep-runs: "3" + pipelinesascode.tekton.dev/on-cel-expression: event == "pull_request" && target_branch + == "main" + creationTimestamp: null + labels: + appstudio.openshift.io/application: dummy-konflux + appstudio.openshift.io/component: konflux-ui-test + pipelines.appstudio.openshift.io/type: build + name: konflux-ui-test-on-pull-request + namespace: abhindas-tenant +spec: + params: + - name: git-url + value: '{{source_url}}' + - name: revision + value: '{{revision}}' + - name: output-image + value: quay.io/redhat-user-workloads-stage/abhindas-tenant/konflux-ui-test:on-pr-{{revision}} + - name: image-expires-after + value: 5d + - name: dockerfile + value: Dockerfile + pipelineSpec: + description: | + This pipeline is ideal for building container images from a Containerfile while maintaining trust after pipeline customization. + + _Uses `buildah` to create a container image leveraging [trusted artifacts](https://konflux-ci.dev/architecture/ADR/0036-trusted-artifacts.html). It also optionally creates a source image and runs some build-time tests. Information is shared between tasks using OCI artifacts instead of PVCs. EC will pass the [`trusted_task.trusted`](https://conforma.dev/docs/policy/packages/release_trusted_task.html#trusted_task__trusted) policy as long as all data used to build the artifact is generated from trusted tasks. + This pipeline is pushed as a Tekton bundle to [quay.io](https://quay.io/repository/konflux-ci/tekton-catalog/pipeline-docker-build-oci-ta?tab=tags)_ + params: + - description: Source Repository URL + name: git-url + type: string + - default: "" + description: Revision of the Source Repository + name: revision + type: string + - description: Fully Qualified Output Image + name: output-image + type: string + - default: . + description: Path to the source code of an application's component from where + to build image. + name: path-context + type: string + - default: Dockerfile + description: Path to the Dockerfile inside the context specified by parameter + path-context + name: dockerfile + type: string + - default: "false" + description: Skip checks against built image + name: skip-checks + type: string + - default: "false" + description: Execute the build with network isolation + name: hermetic + type: string + - default: "" + description: Build dependencies to be prefetched + name: prefetch-input + type: string + - default: "" + description: Image tag expiration time, time values could be something like + 1h, 2d, 3w for hours, days, and weeks, respectively. + name: image-expires-after + type: string + - default: "false" + description: Build a source image. + name: build-source-image + type: string + - default: "false" + description: Add built image into an OCI image index + name: build-image-index + type: string + - default: docker + description: The format for the resulting image's mediaType. Valid values are + oci or docker. + name: buildah-format + type: string + - default: "false" + description: Enable cache proxy configuration + name: enable-cache-proxy + - default: [] + description: Array of --build-arg values ("arg=value" strings) for buildah + name: build-args + type: array + - default: "" + description: Path to a file with build arguments for buildah, see https://www.mankier.com/1/buildah-build#--build-arg-file + name: build-args-file + type: string + - default: "false" + description: Whether to enable privileged mode, should be used only with remote + VMs + name: privileged-nested + type: string + results: + - description: "" + name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - description: "" + name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - description: "" + name: CHAINS-GIT_URL + value: $(tasks.clone-repository.results.url) + - description: "" + name: CHAINS-GIT_COMMIT + value: $(tasks.clone-repository.results.commit) + tasks: + - name: init + params: + - name: enable-cache-proxy + value: $(params.enable-cache-proxy) + taskRef: + params: + - name: name + value: init + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-init:0.4@sha256:288f3106118edc1d0f0c79a89c960abf5841a4dd8bc3f38feb10527253105b19 + - name: kind + value: task + resolver: bundles + - name: clone-repository + params: + - name: url + value: $(params.git-url) + - name: revision + value: $(params.revision) + - name: ociStorage + value: $(params.output-image).git + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - init + taskRef: + params: + - name: name + value: git-clone-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:2c388d28651457db60bb90287e7d8c3680303197196e4476878d98d81e8b6dc9 + - name: kind + value: task + resolver: bundles + workspaces: + - name: basic-auth + workspace: git-auth + - name: prefetch-dependencies + params: + - name: input + value: $(params.prefetch-input) + - name: SOURCE_ARTIFACT + value: $(tasks.clone-repository.results.SOURCE_ARTIFACT) + - name: ociStorage + value: $(params.output-image).prefetch + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - clone-repository + taskRef: + params: + - name: name + value: prefetch-dependencies-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:22612d629796a29ddd177d6e29c18a4319875d4e2348286ea01d16427cec0dc1 + - name: kind + value: task + resolver: bundles + workspaces: + - name: git-basic-auth + workspace: git-auth + - name: netrc + workspace: netrc + - name: build-container + params: + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: PRIVILEGED_NESTED + value: $(params.privileged-nested) + - name: SOURCE_URL + value: $(tasks.clone-repository.results.url) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + - name: HTTP_PROXY + value: $(tasks.init.results.http-proxy) + - name: NO_PROXY + value: $(tasks.init.results.no-proxy) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - prefetch-dependencies + taskRef: + params: + - name: name + value: buildah-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-buildah-oci-ta:0.9@sha256:8db8c8fe3dcbf75a7ae2e55691d9b68823e106ebe302ef89556e8b71484c3725 + - name: kind + value: task + resolver: bundles + - name: build-image-index + params: + - name: IMAGE + value: $(params.output-image) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: ALWAYS_BUILD_INDEX + value: $(params.build-image-index) + - name: IMAGES + value: + - $(tasks.build-container.results.IMAGE_URL)@$(tasks.build-container.results.IMAGE_DIGEST) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + runAfter: + - build-container + taskRef: + params: + - name: name + value: build-image-index + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:ac4f8b58ade5000f6e47d287b72832f0d89a91651849467be73e05da639cff7d + - name: kind + value: task + resolver: bundles + - name: build-source-image + params: + - name: BINARY_IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: BINARY_IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: source-build-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:eb620d137d2dfa9966d991ac210ad14f391cfa9cfc501e3cc1eb24e3332c6986 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.build-source-image) + operator: in + values: + - "true" + - name: deprecated-base-image-check + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: deprecated-image-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clair-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clair-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:654b989d7cdc03d082e56f216a29de04847215ee379a8d9ca315e453ad2b15c2 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: ecosystem-cert-preflight-checks + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: ecosystem-cert-preflight-checks + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:945f8ba72381402ce6b00efa24a6eeb19a27ba68b445474c28ebfbfb21bb365f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-snyk-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-snyk-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:49b7d09db82e6cad98152db8f16707ca3d90a1709e846e3ed8c91a433c88724f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clamav-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clamav-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:b2f25599a10ab0846e4659f76b5b78c0fddf561404656fda52055eda31e70d83 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-coverity-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - coverity-availability-check + taskRef: + params: + - name: name + value: sast-coverity-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-coverity-check-oci-ta:0.3@sha256:9978b6163d54473a72ded5eb9b75d9ffae92118e544c7b96dc805cd66870b12d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - input: $(tasks.coverity-availability-check.results.STATUS) + operator: in + values: + - success + - name: coverity-availability-check + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: coverity-availability-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-coverity-availability-check:0.2@sha256:267d5bc069a0323f41e24732ddfd1057e5c639e853d1e620c67505fab78f1301 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-shell-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-shell-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:e7a51575f9188a1461d4520da25aaa4efdd3b896c97dc750941fa22840e55c13 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-unicode-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-unicode-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:0ca0203c25e22c9f12cc32436f6bf02df19fd177ba5f84926d804c711146974e + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: apply-tags + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: apply-tags + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:510b6d2a3b188adeb716e49566b57d611ab36bd69a2794b5ddfc11dbf014c2ca + - name: kind + value: task + resolver: bundles + - name: push-dockerfile + params: + - name: IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: push-dockerfile-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.3@sha256:322d515ca66d92188067344761733d1e5c64d4b7bb790d10f35540da5e6289f1 + - name: kind + value: task + resolver: bundles + - name: rpms-signature-scan + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: rpms-signature-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:47b81d6b3d752649eddfbb8b3fd8f6522c4bb07f6d1946f9bc45dae3f92e2c9a + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + workspaces: + - name: git-auth + optional: true + - name: netrc + optional: true + taskRunTemplate: + serviceAccountName: build-pipeline-konflux-ui-test + workspaces: + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' +status: {} diff --git a/.tekton/konflux-ui-test-push.yaml b/.tekton/konflux-ui-test-push.yaml new file mode 100644 index 00000000..7b1ffb65 --- /dev/null +++ b/.tekton/konflux-ui-test-push.yaml @@ -0,0 +1,580 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + annotations: + build.appstudio.openshift.io/repo: https://github.com/abhinandan13jan/konflux-ui-test?rev={{revision}} + build.appstudio.redhat.com/commit_sha: '{{revision}}' + build.appstudio.redhat.com/target_branch: '{{target_branch}}' + pipelinesascode.tekton.dev/cancel-in-progress: "false" + pipelinesascode.tekton.dev/max-keep-runs: "3" + pipelinesascode.tekton.dev/on-cel-expression: event == "push" && target_branch + == "main" + creationTimestamp: null + labels: + appstudio.openshift.io/application: dummy-konflux + appstudio.openshift.io/component: konflux-ui-test + pipelines.appstudio.openshift.io/type: build + name: konflux-ui-test-on-push + namespace: abhindas-tenant +spec: + params: + - name: git-url + value: '{{source_url}}' + - name: revision + value: '{{revision}}' + - name: output-image + value: quay.io/redhat-user-workloads-stage/abhindas-tenant/konflux-ui-test:{{revision}} + - name: dockerfile + value: Dockerfile + pipelineSpec: + description: | + This pipeline is ideal for building container images from a Containerfile while maintaining trust after pipeline customization. + + _Uses `buildah` to create a container image leveraging [trusted artifacts](https://konflux-ci.dev/architecture/ADR/0036-trusted-artifacts.html). It also optionally creates a source image and runs some build-time tests. Information is shared between tasks using OCI artifacts instead of PVCs. EC will pass the [`trusted_task.trusted`](https://conforma.dev/docs/policy/packages/release_trusted_task.html#trusted_task__trusted) policy as long as all data used to build the artifact is generated from trusted tasks. + This pipeline is pushed as a Tekton bundle to [quay.io](https://quay.io/repository/konflux-ci/tekton-catalog/pipeline-docker-build-oci-ta?tab=tags)_ + params: + - description: Source Repository URL + name: git-url + type: string + - default: "" + description: Revision of the Source Repository + name: revision + type: string + - description: Fully Qualified Output Image + name: output-image + type: string + - default: . + description: Path to the source code of an application's component from where + to build image. + name: path-context + type: string + - default: Dockerfile + description: Path to the Dockerfile inside the context specified by parameter + path-context + name: dockerfile + type: string + - default: "false" + description: Skip checks against built image + name: skip-checks + type: string + - default: "false" + description: Execute the build with network isolation + name: hermetic + type: string + - default: "" + description: Build dependencies to be prefetched + name: prefetch-input + type: string + - default: "" + description: Image tag expiration time, time values could be something like + 1h, 2d, 3w for hours, days, and weeks, respectively. + name: image-expires-after + type: string + - default: "false" + description: Build a source image. + name: build-source-image + type: string + - default: "false" + description: Add built image into an OCI image index + name: build-image-index + type: string + - default: docker + description: The format for the resulting image's mediaType. Valid values are + oci or docker. + name: buildah-format + type: string + - default: "false" + description: Enable cache proxy configuration + name: enable-cache-proxy + - default: [] + description: Array of --build-arg values ("arg=value" strings) for buildah + name: build-args + type: array + - default: "" + description: Path to a file with build arguments for buildah, see https://www.mankier.com/1/buildah-build#--build-arg-file + name: build-args-file + type: string + - default: "false" + description: Whether to enable privileged mode, should be used only with remote + VMs + name: privileged-nested + type: string + results: + - description: "" + name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - description: "" + name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - description: "" + name: CHAINS-GIT_URL + value: $(tasks.clone-repository.results.url) + - description: "" + name: CHAINS-GIT_COMMIT + value: $(tasks.clone-repository.results.commit) + tasks: + - name: init + params: + - name: enable-cache-proxy + value: $(params.enable-cache-proxy) + taskRef: + params: + - name: name + value: init + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-init:0.4@sha256:288f3106118edc1d0f0c79a89c960abf5841a4dd8bc3f38feb10527253105b19 + - name: kind + value: task + resolver: bundles + - name: clone-repository + params: + - name: url + value: $(params.git-url) + - name: revision + value: $(params.revision) + - name: ociStorage + value: $(params.output-image).git + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - init + taskRef: + params: + - name: name + value: git-clone-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.1@sha256:2c388d28651457db60bb90287e7d8c3680303197196e4476878d98d81e8b6dc9 + - name: kind + value: task + resolver: bundles + workspaces: + - name: basic-auth + workspace: git-auth + - name: prefetch-dependencies + params: + - name: input + value: $(params.prefetch-input) + - name: SOURCE_ARTIFACT + value: $(tasks.clone-repository.results.SOURCE_ARTIFACT) + - name: ociStorage + value: $(params.output-image).prefetch + - name: ociArtifactExpiresAfter + value: $(params.image-expires-after) + runAfter: + - clone-repository + taskRef: + params: + - name: name + value: prefetch-dependencies-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-prefetch-dependencies-oci-ta:0.2@sha256:22612d629796a29ddd177d6e29c18a4319875d4e2348286ea01d16427cec0dc1 + - name: kind + value: task + resolver: bundles + workspaces: + - name: git-basic-auth + workspace: git-auth + - name: netrc + workspace: netrc + - name: build-container + params: + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: PRIVILEGED_NESTED + value: $(params.privileged-nested) + - name: SOURCE_URL + value: $(tasks.clone-repository.results.url) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + - name: HTTP_PROXY + value: $(tasks.init.results.http-proxy) + - name: NO_PROXY + value: $(tasks.init.results.no-proxy) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - prefetch-dependencies + taskRef: + params: + - name: name + value: buildah-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-buildah-oci-ta:0.9@sha256:8db8c8fe3dcbf75a7ae2e55691d9b68823e106ebe302ef89556e8b71484c3725 + - name: kind + value: task + resolver: bundles + - name: build-image-index + params: + - name: IMAGE + value: $(params.output-image) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: ALWAYS_BUILD_INDEX + value: $(params.build-image-index) + - name: IMAGES + value: + - $(tasks.build-container.results.IMAGE_URL)@$(tasks.build-container.results.IMAGE_DIGEST) + - name: BUILDAH_FORMAT + value: $(params.buildah-format) + runAfter: + - build-container + taskRef: + params: + - name: name + value: build-image-index + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-build-image-index:0.2@sha256:ac4f8b58ade5000f6e47d287b72832f0d89a91651849467be73e05da639cff7d + - name: kind + value: task + resolver: bundles + - name: build-source-image + params: + - name: BINARY_IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: BINARY_IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: source-build-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:eb620d137d2dfa9966d991ac210ad14f391cfa9cfc501e3cc1eb24e3332c6986 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.build-source-image) + operator: in + values: + - "true" + - name: deprecated-base-image-check + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: deprecated-image-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-deprecated-image-check:0.5@sha256:808fe09bb5b8503de569de097ae5dd619a7488110f79e8e215e69862ee3fce6d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clair-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clair-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clair-scan:0.3@sha256:654b989d7cdc03d082e56f216a29de04847215ee379a8d9ca315e453ad2b15c2 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: ecosystem-cert-preflight-checks + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: ecosystem-cert-preflight-checks + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-ecosystem-cert-preflight-checks:0.2@sha256:945f8ba72381402ce6b00efa24a6eeb19a27ba68b445474c28ebfbfb21bb365f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-snyk-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-snyk-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-snyk-check-oci-ta:0.4@sha256:49b7d09db82e6cad98152db8f16707ca3d90a1709e846e3ed8c91a433c88724f + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: clamav-scan + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: clamav-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-clamav-scan:0.3@sha256:b2f25599a10ab0846e4659f76b5b78c0fddf561404656fda52055eda31e70d83 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-coverity-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE + value: $(params.output-image) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: HERMETIC + value: $(params.hermetic) + - name: PREFETCH_INPUT + value: $(params.prefetch-input) + - name: IMAGE_EXPIRES_AFTER + value: $(params.image-expires-after) + - name: COMMIT_SHA + value: $(tasks.clone-repository.results.commit) + - name: BUILD_ARGS + value: + - $(params.build-args[*]) + - name: BUILD_ARGS_FILE + value: $(params.build-args-file) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - coverity-availability-check + taskRef: + params: + - name: name + value: sast-coverity-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-coverity-check-oci-ta:0.3@sha256:9978b6163d54473a72ded5eb9b75d9ffae92118e544c7b96dc805cd66870b12d + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - input: $(tasks.coverity-availability-check.results.STATUS) + operator: in + values: + - success + - name: coverity-availability-check + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: coverity-availability-check + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-coverity-availability-check:0.2@sha256:267d5bc069a0323f41e24732ddfd1057e5c639e853d1e620c67505fab78f1301 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-shell-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-shell-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-shell-check-oci-ta:0.1@sha256:e7a51575f9188a1461d4520da25aaa4efdd3b896c97dc750941fa22840e55c13 + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: sast-unicode-check + params: + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + - name: CACHI2_ARTIFACT + value: $(tasks.prefetch-dependencies.results.CACHI2_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: sast-unicode-check-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-sast-unicode-check-oci-ta:0.4@sha256:0ca0203c25e22c9f12cc32436f6bf02df19fd177ba5f84926d804c711146974e + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + - name: apply-tags + params: + - name: IMAGE_URL + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: apply-tags + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:510b6d2a3b188adeb716e49566b57d611ab36bd69a2794b5ddfc11dbf014c2ca + - name: kind + value: task + resolver: bundles + - name: push-dockerfile + params: + - name: IMAGE + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: IMAGE_DIGEST + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + - name: DOCKERFILE + value: $(params.dockerfile) + - name: CONTEXT + value: $(params.path-context) + - name: SOURCE_ARTIFACT + value: $(tasks.prefetch-dependencies.results.SOURCE_ARTIFACT) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: push-dockerfile-oci-ta + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-push-dockerfile-oci-ta:0.3@sha256:322d515ca66d92188067344761733d1e5c64d4b7bb790d10f35540da5e6289f1 + - name: kind + value: task + resolver: bundles + - name: rpms-signature-scan + params: + - name: image-url + value: $(tasks.build-image-index.results.IMAGE_URL) + - name: image-digest + value: $(tasks.build-image-index.results.IMAGE_DIGEST) + runAfter: + - build-image-index + taskRef: + params: + - name: name + value: rpms-signature-scan + - name: bundle + value: quay.io/konflux-ci/tekton-catalog/task-rpms-signature-scan:0.2@sha256:47b81d6b3d752649eddfbb8b3fd8f6522c4bb07f6d1946f9bc45dae3f92e2c9a + - name: kind + value: task + resolver: bundles + when: + - input: $(params.skip-checks) + operator: in + values: + - "false" + workspaces: + - name: git-auth + optional: true + - name: netrc + optional: true + taskRunTemplate: + serviceAccountName: build-pipeline-konflux-ui-test + workspaces: + - name: git-auth + secret: + secretName: '{{ git_auth_secret }}' +status: {} diff --git a/deploy-konflux-ci.yaml b/deploy-konflux-ci.yaml new file mode 100644 index 00000000..68929c9b --- /dev/null +++ b/deploy-konflux-ci.yaml @@ -0,0 +1,247 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: deploy-konflux-ci + labels: + konflux-ci/kind: "true" + app.kubernetes.io/version: "0.2" + upstream-usable: "true" + annotations: + tekton.dev/pipelines.minVersion: "0.44.x" + tekton.dev/tags: konflux +spec: + description: | + This task performs a full Konflux CI deployment. It clones the specified Git repository, + checks out the desired branch, and runs deployment scripts using a kubeconfig retrieved from + a Kubernetes secret. It is intended for use in OpenShift Pipelines or other Tekton environments. + + params: + - name: cluster-access-secret + description: Name of the Kubernetes Secret that contains the kubeconfig (base64 encoded) used to access the target cluster. + - name: repo-url + description: URL of the Git repository containing the Konflux CI deployment scripts. + default: https://github.com/konflux-ci/konflux-ci.git + - name: repo-branch + description: Git branch to check out when cloning the repository. + default: main + - name: create-test-resources + description: 'Indicates if a set of test resources should be installed' + default: 'true' + - name: component-name + description: | + The GitHub repository name of the Konflux CI component to customize (e.g., `build-service`, `release-service`). + Used for applying image or Kubernetes manifest overrides. + default: '' + - name: component-image-repository + description: | + Overrides the container image repository for the `component-name` (e.g., `quay.io/my-org/my-custom-image`). + default: '' + - name: component-image-tag + description: | + Overrides the container image tag for the `component-name` (e.g., `latest`, `my-feature-branch`). + default: '' + - name: component-pr-owner + description: | + GitHub owner (user|org) of the fork/PR providing custom Kubernetes manifests for the `component-name`. + default: '' + - name: component-pr-sha + description: | + Commit SHA of the PR (from `component-pr-owner`) supplying custom Kubernetes manifests for the `component-name`. + default: '' + - name: component-pr-source-branch + description: | + GitHub source branch of the pull request. + default: '' + - name: oci-ref + type: string + description: Full OCI artifact reference in a format "quay.io/org/repo:tag. It's used for storing logs from the Task's Steps + - name: oci-credentials + type: string + description: | + The secret name containing credentials for container registry where the artifacts will be stored. + The secret should contain `data.oci-storage-dockerconfigjson: ` + default: "konflux-test-infra" + + volumes: + - name: credentials + secret: + secretName: $(params.cluster-access-secret) + - name: workdir + emptyDir: {} + - name: logs + emptyDir: {} + - name: konflux-test-infra-volume + secret: + secretName: $(params.oci-credentials) + + stepTemplate: + env: + - name: KUBECONFIG + value: '/credentials/kubeconfig' + - name: LOG_FILENAME + value: '/var/log-dir/deploy-konflux-ci.log' + volumeMounts: + - name: credentials + mountPath: /credentials + - name: workdir + mountPath: /var/workdir + - name: logs + mountPath: /var/log-dir/ + + steps: + - name: clone-konflux-ci + image: quay.io/openshift-pipeline/pipelines-git-init-rhel9@sha256:7eee14366c516d92cf7480c9bc256cf0e544bf06da5d46ffb5e8bfe3e448326c + onError: continue + workingDir: /var/workdir + securityContext: + runAsUser: 0 + args: + - -url=$(params.repo-url) + - -revision=$(params.repo-branch) + - -path=. + - name: solve-pr-pairing + image: quay.io/konflux-ci/tekton-integration-catalog/utils:latest + onError: continue + workingDir: /var/workdir + when: + - input: "$(params.component-name)" + operator: notin + values: [""] + env: + - name: COMPONENT_NAME + value: "$(params.component-name)" + - name: PR_SOURCE_BRANCH + value: "$(params.component-pr-source-branch)" + - name: PR_AUTHOR + value: "$(params.component-pr-owner)" + - name: PR_SHA + value: "$(params.component-pr-sha)" + script: | + #!/bin/bash + set -euo pipefail + + { + echo "[INFO] Fetching and executing solve-pr-pairing.sh..." + curl -sSfL https://raw.githubusercontent.com/konflux-ci/tekton-integration-catalog/main/scripts/konflux-ci-deploy/solve-pr-pairing.sh | bash + } 2>&1 | tee -a $LOG_FILENAME + - name: update-kustomization + image: quay.io/konflux-ci/tekton-integration-catalog/utils:latest + onError: continue + workingDir: /var/workdir + when: + - input: "$(params.component-name)" + operator: notin + values: [""] + script: | + #!/bin/bash + set -euo pipefail + + { + if [ -f /var/workdir/.env ]; then + echo "[INFO] Loading env vars from /var/workdir/.env: $(cat /var/workdir/.env)" + source /var/workdir/.env + else + echo "[INFO] Loading env vars from parameters" + + COMPONENT_NAME="$(params.component-name)" + IMAGE_REPO="$(params.component-image-repository)" + IMAGE_TAG="$(params.component-image-tag)" + PR_OWNER="$(params.component-pr-owner)" + PR_SHA="$(params.component-pr-sha)" + fi + + # Repo names do not match the ones of the component. Try to find the right kustomization.yaml based on the component name. + KUSTOMIZATION_PATH=$(find konflux-ci/ -type f -name "kustomization.yaml" -path "*${COMPONENT_NAME%-service}*/core/*" | head -n 1) + + # Check if the file exists + if [[ ! -f "${KUSTOMIZATION_PATH}" ]]; then + echo "[WARNING] No substitutions will be applied as the kustomization file for $(params.component-name) has not been found." + exit 0 + fi + + # Apply substitutions + if [[ -n "$IMAGE_REPO" ]]; then + echo "[INFO] Updating image repository to $IMAGE_REPO" + yq -i e "(.images.[] | select(.name==\"quay.io/konflux-ci/${COMPONENT_NAME}\")) |= .newName=\"${IMAGE_REPO}\"" "$KUSTOMIZATION_PATH" + fi + + if [[ -n "$IMAGE_TAG" ]]; then + echo "[INFO] Updating image tag to $IMAGE_TAG" + yq -i e "(.images.[] | select(.name==\"quay.io/konflux-ci/${COMPONENT_NAME}\")) |= .newTag=\"${IMAGE_TAG}\"" "$KUSTOMIZATION_PATH" + fi + + if [[ -n "$PR_OWNER" && -n "$PR_SHA" ]]; then + echo "[INFO] Updating GitHub reference to $PR_OWNER@$PR_SHA" + yq -i e "(.resources[] | select(. ==\"*github.com/konflux-ci/${COMPONENT_NAME}/config/default*\")) |= \"https://github.com/${PR_OWNER}/${COMPONENT_NAME}/config/default?ref=${PR_SHA}\"" "$KUSTOMIZATION_PATH" + yq -i e "(.resources[] | select(. ==\"*github.com/konflux-ci/${COMPONENT_NAME}/config/snapshotgc*\")) |= \"https://github.com/${PR_OWNER}/${COMPONENT_NAME}/config/snapshotgc?ref=${PR_SHA}\"" "$KUSTOMIZATION_PATH" + fi + } 2>&1 | tee -a $LOG_FILENAME + + - name: deploy + image: quay.io/konflux-ci/tekton-integration-catalog/utils:latest + onError: continue + workingDir: /var/workdir + script: | + #!/bin/bash + set -euo pipefail + + { + kubectl cluster-info + + echo "[INFO] Installing Konflux CI dependencies" + ./deploy-deps.sh + ./wait-for-all.sh + + echo "[INFO] Installing Konflux CI..." + ./deploy-konflux.sh + + kubectl get po -A + } 2>&1 | tee -a $LOG_FILENAME + - name: create-test-resources + image: quay.io/konflux-ci/tekton-integration-catalog/utils:latest + onError: continue + workingDir: /var/workdir + when: + - input: "$(params.create-test-resources)" + operator: in + values: ["true"] + script: | + #!/bin/bash + set -euo pipefail + + { + echo "[INFO] Applying Kyverno to reduce resources for testing" + kubectl apply -f ./dependencies/kyverno/policy/e2e-reduce-resources.yaml + + echo "[INFO] Creating Test Resources..." + ./deploy-test-resources.sh + } 2>&1 | tee -a $LOG_FILENAME + + - name: secure-push-oci + ref: + resolver: git + params: + - name: url + value: https://github.com/konflux-ci/tekton-integration-catalog.git + - name: revision + value: main + - name: pathInRepo + value: stepactions/secure-push-oci/0.1/secure-push-oci.yaml + params: + - name: workdir-path + value: /var/log-dir/ + - name: oci-ref + value: $(params.oci-ref) + - name: credentials-volume-name + value: konflux-test-infra-volume + - name: fail-if-any-step-failed + ref: + resolver: git + params: + - name: url + value: https://github.com/konflux-ci/tekton-integration-catalog.git + - name: revision + value: main + - name: pathInRepo + value: stepactions/fail-if-any-step-failed/0.1/fail-if-any-step-failed.yaml diff --git a/integration-tests/IntegrationTestScenarios/e2e-konflux-ui.yaml b/integration-tests/IntegrationTestScenarios/e2e-konflux-ui.yaml new file mode 100644 index 00000000..bfa4af4a --- /dev/null +++ b/integration-tests/IntegrationTestScenarios/e2e-konflux-ui.yaml @@ -0,0 +1,38 @@ +apiVersion: appstudio.redhat.com/v1beta2 +kind: IntegrationTestScenario +metadata: + labels: + test.appstudio.openshift.io/optional: 'false' + name: konflux-ui-e2e +spec: + application: konflux-ui-test + contexts: + - description: execute the integration test in all cases - this would be the default state + name: application + - description: execute the integration test for a Snapshot created for a `pull request` event + name: pull_request + params: + - name: konflux-test-infra-secret + value: konflux-test-infra + - name: oci-credentials-secret + value: quay-secret + - name: github-credentials-secret + value: github-credentials + - name: cypress-credentials-secret + value: cypress-credentials + - name: cypress-cloud-secret + value: cypress-cloud-credentials-disabled + - name: slack-credentials-secret + value: slack-credentials + - name: debug-pause-minutes + value: "10" + resolverRef: + params: + - name: url + value: https://github.com/testcara/konflux-ui-test + - name: revision + value: main + - name: pathInRepo + value: integration-tests/Pipelines/e2e-main-pipeline.yaml + resolver: git + resourceKind: pipeline diff --git a/integration-tests/PLRs/PipelineRuns.yaml b/integration-tests/PLRs/PipelineRuns.yaml new file mode 100644 index 00000000..e0497fdc --- /dev/null +++ b/integration-tests/PLRs/PipelineRuns.yaml @@ -0,0 +1,31 @@ +apiVersion: tekton.dev/v1beta1 +kind: PipelineRun +metadata: + generateName: e2e-test- + namespace: wlin-tenant +spec: + pipelineRef: + resolver: git + params: + - name: url + value: https://github.com/testcara/konflux-ui-test + - name: revision + value: main + - name: pathInRepo + value: integration-tests/Pipelines/e2e-main-pipeline.yaml + params: + # IMPORTANT: Replace with actual component name and image from your build + # Example: quay.io/redhat-user-workloads-stage/wlin-tenant/cara-konflux-ui-test-b1228@sha256:... + - name: SNAPSHOT + value: '{"components": [{"name":"cara-konflux-ui-test-b1228", "containerImage": "quay.io/redhat-user-workloads-stage/wlin-tenant/cara-konflux-ui-test-b1228:latest"}]}' + - name: konflux-test-infra-secret + value: konflux-test-infra + - name: oci-credentials-secret + value: quay-secret + - name: github-credentials-secret + value: github-credentials + - name: cypress-credentials-secret + value: cypress-credentials + - name: slack-credentials-secret + value: slack-credentials + timeout: 2h0m0s diff --git a/integration-tests/Pipelines/e2e-main-pipeline.yaml b/integration-tests/Pipelines/e2e-main-pipeline.yaml new file mode 100644 index 00000000..64c50f49 --- /dev/null +++ b/integration-tests/Pipelines/e2e-main-pipeline.yaml @@ -0,0 +1,303 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: e2e-main-pipeline + namespace: wlin-tenant +spec: + params: + - name: SNAPSHOT + description: 'The JSON string representing the snapshot of the application under test.' + default: '{"components": [{"name":"test-app", "containerImage": "quay.io/example/repo:latest"}]}' + type: string + - name: konflux-test-infra-secret + description: The name of secret where testing infrastructures credentials are stored. + type: string + - name: oci-container-repo + default: 'quay.io/carawang/konflux-ui-test' + description: The ORAS container used to store all test artifacts. + - name: e2e-artifacts-repo + default: 'quay.io/konflux_ui_qe/pr-check-artefacts' + description: The OCI repository to store E2E test artifacts (videos, screenshots, reports) + type: string + - name: artifact-browser-url + description: 'URL to the artifact browser deployment. If provided, a link will be added to PR comments.' + default: '' + type: string + - name: github-credentials-secret + description: 'Secret name containing GitHub token' + default: 'github-credentials' + type: string + - name: cypress-credentials-secret + description: 'Secret name containing Cypress credentials' + default: 'cypress-credentials' + type: string + - name: cypress-cloud-secret + description: 'Secret name containing Cypress Cloud credentials' + default: 'cypress-cloud-credentials' + type: string + - name: slack-credentials-secret + description: 'Secret name containing Slack credentials' + default: 'slack-credentials' + type: string + - name: oci-credentials-secret + description: 'Secret name containing OCI registry credentials (Quay.io)' + default: 'quay-secret' + type: string + - name: skip-provision + description: 'Skip provisioning Kind cluster (use existing cluster for debugging)' + default: 'false' + type: string + - name: skip-deploy + description: 'Skip deploying Konflux (use existing deployment for debugging)' + default: 'false' + type: string + - name: skip-deprovision + description: 'Skip deprovisioning Kind cluster (keep cluster for debugging)' + default: 'false' + type: string + - name: cluster-kubeconfig-secret + description: 'Name of cluster kubeconfig secret. Use existing secret name when skip-provision=true, or leave empty for auto-generated name.' + default: '' + type: string + - name: debug-pause-minutes + description: 'Minutes to pause for manual debugging after port-forward setup (0 to skip)' + default: '0' + type: string + tasks: + - name: konflux-ui-pr-metadata + taskRef: + resolver: git + params: + - name: url + value: https://github.com/testcara/konflux-ui-test + - name: revision + value: main + - name: pathInRepo + value: integration-tests/Tasks/konflux-ui-pr-metadata.yaml + params: + - name: SNAPSHOT + value: $(params.SNAPSHOT) + - name: test-name + value: $(context.pipelineRun.name) + - name: show-snapshot-data + taskRef: + resolver: git + params: + - name: url + value: https://github.com/testcara/konflux-ui-test + - name: revision + value: main + - name: pathInRepo + value: integration-tests/Tasks/show-snapshot-data.yaml + params: + - name: snapshot + value: $(params.SNAPSHOT) + - name: check-org-membership + runAfter: + - show-snapshot-data + - konflux-ui-pr-metadata + taskRef: + resolver: git + params: + - name: url + value: https://github.com/testcara/konflux-ui-test + - name: revision + value: main + - name: pathInRepo + value: integration-tests/Tasks/check-org-membership.yaml + params: + - name: job-spec + value: $(tasks.konflux-ui-pr-metadata.results.job-spec) + - name: github-credentials-secret + value: $(params.github-credentials-secret) + - name: provision-kind-cluster + runAfter: + - check-org-membership + when: + - input: '$(tasks.konflux-ui-pr-metadata.results.pull-request-author)' + operator: notin + values: ['red-hat-konflux[bot]'] + - input: '$(params.skip-provision)' + operator: in + values: ['false'] + taskRef: + resolver: git + params: + - name: url + value: https://github.com/konflux-ci/tekton-integration-catalog + - name: revision + value: main + - name: pathInRepo + value: tasks/mapt-oci/kind-aws-spot/provision/0.2/kind-aws-provision.yaml + params: + - name: secret-aws-credentials + value: $(params.konflux-test-infra-secret) + - name: cluster-access-secret-name + value: kfg-$(context.pipelineRun.name) + - name: id + value: $(context.pipelineRun.name) + - name: tags + value: 'owner=konflux-devprod@redhat.com,project=Konflux,created-by=integration-pipeline,component=release-service-catalog' + - name: debug + value: 'false' + - name: ownerKind + value: PipelineRun + - name: ownerName + value: $(context.pipelineRun.name) + - name: ownerUid + value: $(context.pipelineRun.uid) + - name: oci-ref + value: $(params.oci-container-repo):$(context.pipelineRun.name) + - name: oci-credentials + value: $(params.oci-credentials-secret) + - name: cpus + value: '4' + - name: memory + value: '16' + - name: compute-sizes + value: 'm5.xlarge,m5a.xlarge,m5d.xlarge,m6i.xlarge,m6a.xlarge,m7i.xlarge,t3.xlarge,t3a.xlarge' + - name: deploy-konflux + when: + - input: '$(tasks.konflux-ui-pr-metadata.results.pull-request-author)' + operator: notin + values: ['red-hat-konflux[bot]'] + - input: '$(params.skip-deploy)' + operator: in + values: ['false'] + runAfter: + - provision-kind-cluster + taskRef: + resolver: git + params: + - name: url + value: https://github.com/konflux-ci/tekton-integration-catalog + - name: revision + value: main + - name: pathInRepo + value: tasks/konflux-ci/deploy/0.2/deploy-konflux-ci.yaml + params: + - name: create-test-resources + value: 'false' + - name: cluster-access-secret + value: kfg-$(context.pipelineRun.name) + - name: component-name + value: release-service-catalog + - name: component-pr-owner + value: $(tasks.konflux-ui-pr-metadata.results.pull-request-author) + - name: component-pr-sha + value: '' + - name: component-pr-source-branch + value: $(tasks.konflux-ui-pr-metadata.results.source-repo-branch) + - name: oci-ref + value: $(params.oci-container-repo):$(context.pipelineRun.name) + - name: oci-credentials + value: $(params.oci-credentials-secret) + - name: run-e2e-konflux-ui + when: + - input: '$(tasks.konflux-ui-pr-metadata.results.pull-request-author)' + operator: notin + values: ['red-hat-konflux[bot]'] + runAfter: + - deploy-konflux + - check-org-membership + taskRef: + resolver: git + params: + - name: url + value: https://github.com/testcara/konflux-ui-test + - name: revision + value: main + - name: pathInRepo + value: integration-tests/Tasks/run-e2e-konflux-ui.yaml + params: + - name: job-spec + value: '$(tasks.konflux-ui-pr-metadata.results.job-spec)' + - name: git-url + value: 'https://github.com/testcara/konflux-ui-test' + - name: git-revision + value: 'main' + - name: cypress-credentials-secret + value: $(params.cypress-credentials-secret) + - name: cypress-cloud-secret + value: $(params.cypress-cloud-secret) + - name: slack-credentials-secret + value: $(params.slack-credentials-secret) + - name: github-credentials-secret + value: $(params.github-credentials-secret) + - name: cluster-access-secret + value: '$(params.cluster-kubeconfig-secret)' + - name: debug-pause-minutes + value: $(params.debug-pause-minutes) + - name: oci-storage + value: '$(params.e2e-artifacts-repo)' + - name: oci-credentials-secret + value: $(params.oci-credentials-secret) + finally: + - name: deprovision-kind-cluster + when: + - input: '$(tasks.konflux-ui-pr-metadata.results.pull-request-author)' + operator: notin + values: ['red-hat-konflux[bot]'] + - input: '$(params.skip-deprovision)' + operator: in + values: ['false'] + taskRef: + resolver: git + params: + - name: url + value: https://github.com/konflux-ci/tekton-integration-catalog + - name: revision + value: main + - name: pathInRepo + value: tasks/mapt-oci/kind-aws-spot/deprovision/0.1/kind-aws-deprovision.yaml + params: + - name: secret-aws-credentials + value: $(params.konflux-test-infra-secret) + - name: id + value: $(context.pipelineRun.name) + - name: cluster-access-secret + value: kfg-$(context.pipelineRun.name) + - name: oci-container + value: $(params.oci-container-repo):$(context.pipelineRun.name) + - name: oci-credentials + value: $(params.oci-credentials-secret) + - name: pull-request-status-message + when: + - input: '$(tasks.konflux-ui-pr-metadata.results.pull-request-author)' + operator: notin + values: ['red-hat-konflux[bot]'] + taskRef: + resolver: git + params: + - name: url + value: https://github.com/konflux-ci/tekton-integration-catalog.git + - name: revision + value: main + - name: pathInRepo + value: tasks/pull-request-comment/0.1/pull-request-comment.yaml + params: + - name: test-name + value: '$(context.pipelineRun.name)' + - name: oci-container + value: '$(params.oci-container-repo):$(context.pipelineRun.name)' + - name: pipeline-aggregate-status + value: '$(tasks.status)' + - name: pull-request-author + value: '$(tasks.konflux-ui-pr-metadata.results.pull-request-author)' + - name: pull-request-number + value: '$(tasks.konflux-ui-pr-metadata.results.pull-request-number)' + - name: git-repo + value: '$(tasks.konflux-ui-pr-metadata.results.git-repo)' + - name: git-org + value: '$(tasks.konflux-ui-pr-metadata.results.git-org)' + - name: git-revision + value: '$(tasks.konflux-ui-pr-metadata.results.git-revision)' + - name: junit-report-name + value: e2e-report.xml + - name: e2e-log-name + value: e2e-tests.log + - name: cluster-provision-log-name + value: cluster-provision.log + - name: enable-test-results-analysis + value: 'true' diff --git a/integration-tests/Tasks/check-org-membership.yaml b/integration-tests/Tasks/check-org-membership.yaml new file mode 100644 index 00000000..361e5157 --- /dev/null +++ b/integration-tests/Tasks/check-org-membership.yaml @@ -0,0 +1,81 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: check-org-membership + annotations: + tekton.dev/displayName: 'konflux-ui-org-membership' + tekton.dev/categories: 'Pipeline' + tekton.dev/tags: 'config,rhads' +spec: + description: >- + checks org membership for konflux-ui + params: + - name: job-spec + description: 'Job specification metadata' + type: string + - name: github-credentials-secret + description: 'Secret name containing GitHub token' + type: string + default: "github-credentials" + results: + - name: membership-result + description: 'The RHADS configuration content (base64 encoded)' + steps: + - name: check-org-membership + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 + env: + - name: JOB_SPEC + value: $(params.job-spec) + - name: GITHUB_TOKEN + valueFrom: + secretKeyRef: + name: $(params.github-credentials-secret) + key: token + optional: true + script: | + #!/usr/bin/env bash + set -euo pipefail + + # First check event type - if not PR, skip all checks + EVENT_TYPE=$(jq -r '.git.event_type' <<< "$JOB_SPEC") + + if [ "$EVENT_TYPE" != 'pull_request' ]; then + echo "The workflow is not triggered from PR, but $EVENT_TYPE - skipping further checks." + exit 0 + fi + + # Only parse PR-specific fields if this is a PR event + SOURCE_REPO_URL=$(jq -r '.git.source_repo_url' <<< "$JOB_SPEC") + PR_AUTHOR=$(jq -r '.git.pull_request_author // "unknown"' <<< "$JOB_SPEC") + PR_LABELS=$(jq -r '.git.pull_request_labels // ""' <<< "$JOB_SPEC") + + echo "$PR_AUTHOR $PR_LABELS" + + WHITELISTED_BOT_NAME=("red-hat-konflux[bot]" "konflux-staging[bot]") + REQUIRED_LABEL_NAME="ok-to-test" + + ORG=$(jq -r '.git.git_org // "unknown"' <<< "$JOB_SPEC") + + for bot in "${WHITELISTED_BOT_NAME[@]}"; do + if [[ "$bot" == "$PR_AUTHOR" ]]; then + echo "PR author is a whitelisted bot, skipping further checks." + exit 0 + fi + done + + if [[ "$PR_LABELS" == *$REQUIRED_LABEL_NAME* ]]; then + echo "PR has '$REQUIRED_LABEL_NAME' label, skipping further checks." + exit 0 + fi + + ALLOWED_USERS=("Katka92" "rrosatti" "janaki29" "sahil143" "testcara" "milantaky" "StanislavJochman" "JoaoPedroPP" "rakshett" "abhinandan13jan" "marcin-michal") + for author in "${ALLOWED_USERS[@]}"; do + if [[ "$author" == "$PR_AUTHOR" ]]; then + echo "PR author is in ALLOWED_USERS list. Running E2E tests." + exit 0 + fi + done + + echo "Still allowing. change this to exit 1 later" + exit 0 diff --git a/integration-tests/Tasks/konflux-ui-pr-metadata.yaml b/integration-tests/Tasks/konflux-ui-pr-metadata.yaml new file mode 100644 index 00000000..8d0f0904 --- /dev/null +++ b/integration-tests/Tasks/konflux-ui-pr-metadata.yaml @@ -0,0 +1,208 @@ +--- +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: konflux-ui-pr-metadata + labels: + app.kubernetes.io/version: '0.1' + upstream-usable: 'true' + annotations: + tekton.dev/pipelines.minVersion: 0.12.1 + tekton.dev/tags: konflux +spec: + description: | + The `konflux-ui-pr-metadata` Task is responsible for gathering and processing metadata during the execution of a pipeline test. + It collects various Git and repository details, such as the type of event that triggered the pipeline (Push or Pull Request), + the Git URL and revision, PR-labels and details about the container image built during the test. + The task processes metadata labels and annotations, constructs a job specification for the Konflux CI system, + and writes this information to specified results. + results: + - name: test-event-type + description: Indicates if the job is triggered by a Pull Request or a Push event. + - name: pull-request-number + description: The pull request number if the job is triggered by a pull request event. + - name: git-url + description: The Git URL from which the test pipeline is originating. This can be from a fork or the original repository. + - name: git-revision + description: The Git revision (commit SHA) from which the test pipeline is originating. + - name: container-image + description: The container image built from the specified Git revision. + - name: git-org + description: The GitHub organization from which the test is originating. + - name: git-repo + description: The repository from which the test is originating. + - name: pull-request-author + description: The GitHub author of the pull request event. + - name: pull-request-labels + description: The GitHub author of the pull request event. + - name: job-spec + description: The Konflux CI job spec metadata generated. + - name: source-repo-url + description: Will show the source from where a Pull Request was opened. Can be from a fork or upstream. + - name: source-repo-branch + description: Get the branch from the fork or upstream repo where the pipeline is executed. + - name: target-repo-branch + description: The target branch value from the Pull Request or the current branch value in case of push event. + - name: component-name + description: The name of the component that is being executed from Konflux. + params: + - name: SNAPSHOT + description: The JSON string of the Snapshot under test. + - name: test-name + type: string + description: The name of the test being executed. + steps: + - name: test-metadata + image: quay.io/konflux-qe-incubator/konflux-qe-tools:latest + workingDir: /workspace + env: + - name: SNAPSHOT + value: $(params.SNAPSHOT) + - name: EVENT_TYPE + valueFrom: + fieldRef: + fieldPath: metadata.labels['pac.test.appstudio.openshift.io/event-type'] + - name: KONFLUX_COMPONENT_NAME + valueFrom: + fieldRef: + fieldPath: metadata.labels['appstudio.openshift.io/component'] + - name: PULL_REQUEST_NUMBER + valueFrom: + fieldRef: + fieldPath: metadata.labels['pac.test.appstudio.openshift.io/pull-request'] + - name: GIT_ORGANIZATION + valueFrom: + fieldRef: + fieldPath: metadata.labels['pac.test.appstudio.openshift.io/url-org'] + - name: GIT_REPOSITORY + valueFrom: + fieldRef: + fieldPath: metadata.labels['pac.test.appstudio.openshift.io/url-repository'] + - name: SOURCE_REPO_URL + valueFrom: + fieldRef: + fieldPath: metadata.annotations['pac.test.appstudio.openshift.io/source-repo-url'] + - name: SOURCE_REPO_BRANCH + valueFrom: + fieldRef: + fieldPath: metadata.annotations['pac.test.appstudio.openshift.io/source-branch'] + # This value refers to the target branch value in 'pull-request' events and branch value in 'push' events. + # E.g. for push event to 'main' branch this will have the value 'main'. For PR event that targets 'main' branch, this will be also 'main'. + - name: TARGET_REPO_BRANCH + valueFrom: + fieldRef: + fieldPath: metadata.annotations['pac.test.appstudio.openshift.io/branch'] + - name: GROUP_TEST_INFO + valueFrom: + fieldRef: + fieldPath: metadata.annotations['test.appstudio.openshift.io/group-test-info'] + script: | + #!/bin/bash + + # If KONFLUX_COMPONENT_NAME is empty, use the first component from SNAPSHOT + if [[ -z "$KONFLUX_COMPONENT_NAME" ]]; then + KONFLUX_COMPONENT_NAME=$(jq -r '.components[0].name' <<< "$SNAPSHOT") + echo "[INFO] No component label found, using first component: $KONFLUX_COMPONENT_NAME" + fi + + # Extract additional environment variables from SNAPSHOT + GIT_URL=$(jq -r --arg component_name "$KONFLUX_COMPONENT_NAME" '.components[] | select(.name == $component_name) | .source.git.url' <<< "$SNAPSHOT") + GIT_REVISION=$(jq -r --arg component_name "$KONFLUX_COMPONENT_NAME" '.components[] | select(.name == $component_name) | .source.git.revision' <<< "$SNAPSHOT") + COMPONENT_CONTAINER_IMAGE=$(jq -r --arg component_name "$KONFLUX_COMPONENT_NAME" '.components[] | select(.name == $component_name) | .containerImage' <<< "$SNAPSHOT") + + # If GIT_ORGANIZATION or GIT_REPOSITORY are empty, extract from GIT_URL + if [[ -z "$GIT_ORGANIZATION" || -z "$GIT_REPOSITORY" ]]; then + echo "[INFO] Extracting org/repo from GIT_URL: $GIT_URL" + GIT_ORGANIZATION=$(echo "$GIT_URL" | sed -n 's#.*github.com/\([^/]*\)/.*#\1#p') + GIT_REPOSITORY=$(echo "$GIT_URL" | sed -n 's#.*github.com/[^/]*/\([^/]*\).*#\1#p' | sed 's/\.git$//') + fi + + # If PULL_REQUEST_NUMBER is empty, try to extract from GROUP_TEST_INFO + if [[ -z "$PULL_REQUEST_NUMBER" && -n "$GROUP_TEST_INFO" ]]; then + echo "[INFO] Extracting PR number from GROUP_TEST_INFO" + PULL_REQUEST_NUMBER=$(echo "$GROUP_TEST_INFO" | jq -r --arg component "$KONFLUX_COMPONENT_NAME" '.[] | select(.component == $component) | .pullRequestNumber' | head -1) + if [[ -z "$PULL_REQUEST_NUMBER" || "$PULL_REQUEST_NUMBER" == "null" ]]; then + # Fallback: use the first component's PR number + PULL_REQUEST_NUMBER=$(echo "$GROUP_TEST_INFO" | jq -r '.[0].pullRequestNumber') + fi + echo "[INFO] Found PR number: $PULL_REQUEST_NUMBER" + fi + + PR_AUTHOR="$(curl -s https://api.github.com/repos/${GIT_ORGANIZATION}/${GIT_REPOSITORY}/pulls/${PULL_REQUEST_NUMBER} | jq -r .user.login)" + PR_LABELS="$(curl -s https://api.github.com/repos/${GIT_ORGANIZATION}/${GIT_REPOSITORY}/pulls/${PULL_REQUEST_NUMBER} | jq -r .labels)" + + + + if [[ "$EVENT_TYPE" != "push" && -n "$PULL_REQUEST_NUMBER" ]]; then + EVENT_TYPE="pull_request" + elif [[ -z "$PULL_REQUEST_NUMBER" && "$EVENT_TYPE" != "push" ]]; then + EVENT_TYPE="push" + fi + + # For push events, set PR fields to null for valid JSON + if [[ "$EVENT_TYPE" == "push" || -z "$PULL_REQUEST_NUMBER" || "$PULL_REQUEST_NUMBER" == "null" ]]; then + PR_NUMBER_JSON="null" + else + PR_NUMBER_JSON="$PULL_REQUEST_NUMBER" + fi + + if [[ -z "$PR_AUTHOR" || "$PR_AUTHOR" == "null" ]]; then + PR_AUTHOR_JSON="null" + else + PR_AUTHOR_JSON="\"$PR_AUTHOR\"" + fi + + JOB_SPEC=$(cat < $(results.test-event-type.path) + echo -n "$PULL_REQUEST_NUMBER" > $(results.pull-request-number.path) + echo -n "$GIT_ORGANIZATION" > $(results.git-org.path) + echo -n "$GIT_REPOSITORY" > $(results.git-repo.path) + echo -n "$COMPONENT_CONTAINER_IMAGE" > $(results.container-image.path) + echo -n "$GIT_URL" > $(results.git-url.path) + echo -n "$GIT_REVISION" > $(results.git-revision.path) + echo -n "$PR_AUTHOR" > $(results.pull-request-author.path) + echo -n "$PR_LABELS" > $(results.pull-request-labels.path) + echo -n "$JOB_SPEC" > $(results.job-spec.path) + echo -n "$SOURCE_REPO_URL" > $(results.source-repo-url.path) + echo -n "$SOURCE_REPO_BRANCH" > $(results.source-repo-branch.path) + echo -n "$TARGET_REPO_BRANCH" > $(results.target-repo-branch.path) + echo -n "$KONFLUX_COMPONENT_NAME" > $(results.component-name.path) diff --git a/integration-tests/Tasks/run-e2e-konflux-ui.yaml b/integration-tests/Tasks/run-e2e-konflux-ui.yaml new file mode 100644 index 00000000..2cabfe85 --- /dev/null +++ b/integration-tests/Tasks/run-e2e-konflux-ui.yaml @@ -0,0 +1,745 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: run-e2e-konflux-ui + annotations: + tekton.dev/displayName: 'konflux-ui-e2e-tests' + tekton.dev/categories: 'Pipeline' + tekton.dev/tags: 'e2e,cypress,konflux-ui' +spec: + description: >- + Runs E2E tests for Konflux UI using Cypress + params: + - name: job-spec + description: 'Job specification metadata' + type: string + - name: job-type + description: 'Type of job (e.g., periodic-stage, periodic, pr)' + type: string + default: "pr-check" + - name: git-url + description: 'Git repository URL' + type: string + - name: git-revision + description: 'Git revision to checkout' + type: string + default: "main" + - name: cypress-credentials-secret + description: 'Secret name containing Cypress credentials (username, password)' + type: string + default: "cypress-credentials" + - name: slack-credentials-secret + description: 'Secret name containing Slack credentials' + type: string + default: "slack-credentials" + - name: github-credentials-secret + description: 'Secret name containing GitHub token' + type: string + default: "github-credentials" + - name: cluster-access-secret + description: 'Secret name containing kubeconfig for accessing Kind cluster' + type: string + default: "" + - name: cypress-cloud-secret + description: 'Secret name containing Cypress Cloud credentials (project-id, record-key)' + type: string + default: "cypress-cloud-credentials" + - name: debug-pause-minutes + description: 'Minutes to pause after test for artifact inspection (0 to skip, max 60)' + type: string + default: "0" + - name: oci-storage + description: 'OCI repository to store test artifacts (e.g., quay.io/user/repo:tag)' + type: string + default: "" + - name: oci-credentials-secret + description: 'Secret containing OCI registry credentials' + type: string + default: "quay-secret" + results: + - name: e2e-output + description: 'Result of e2e test' + volumes: + - name: kubeconfig + secret: + secretName: $(params.cluster-access-secret) + optional: true + - name: shared-data + emptyDir: {} + - name: oci-credentials + secret: + secretName: $(params.oci-credentials-secret) + optional: true + items: + - key: .dockerconfigjson + path: .dockerconfigjson + sidecars: + - name: port-forward + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 + volumeMounts: + - name: kubeconfig + mountPath: /credentials + - name: shared-data + mountPath: /shared + env: + - name: JOB_TYPE + value: $(params.job-type) + - name: CLUSTER_SECRET + value: $(params.cluster-access-secret) + script: | + #!/usr/bin/env bash + set -euo pipefail + + echo "=== PORT FORWARD SIDECAR START ===" + echo "JOB_TYPE: ${JOB_TYPE}" + echo "cluster-access-secret param: ${CLUSTER_SECRET}" + echo "" + + echo "Checking /credentials:" + ls -la /credentials/ 2>&1 || echo "Dir not found" + echo "" + + if [[ -f /credentials/kubeconfig ]]; then + echo "✓ Found kubeconfig ($(wc -c < /credentials/kubeconfig) bytes)" + else + echo "✗ kubeconfig NOT FOUND" + echo "Secret expected: ${CLUSTER_SECRET}" + find /credentials -type f 2>/dev/null | head -10 + fi + echo "" + + # Skip port forwarding for periodic-stage jobs + if [[ "${JOB_TYPE}" == "periodic-stage" ]]; then + echo "INFO: Skipping port forward for periodic-stage job" + echo "skipped" > /shared/port-forward-status + sleep infinity + exit 0 + fi + + # Check if kubeconfig exists + if [[ ! -f /credentials/kubeconfig ]]; then + echo "ERROR: kubeconfig not found!" + if [[ -z "${CLUSTER_SECRET}" ]]; then + echo "CAUSE: cluster-access-secret parameter is EMPTY" + echo "Check Pipeline taskRef params mapping" + else + echo "CAUSE: Secret '${CLUSTER_SECRET}' not found or missing 'kubeconfig' key" + echo "Verify: kubectl get secret ${CLUSTER_SECRET} -o jsonpath='{.data.kubeconfig}'" + fi + echo "failed" > /shared/port-forward-status + sleep infinity + exit 1 + fi + + export KUBECONFIG=/credentials/kubeconfig + echo "✓ KUBECONFIG set to: ${KUBECONFIG}" + echo "" + + echo "=== Port Forward Sidecar Starting ===" + echo "Waiting for Konflux UI deployment to be ready..." + + # Wait for deployment + kubectl wait --for=condition=available --timeout=300s deployment/proxy -n konflux-ui || { + echo "ERROR: Konflux UI proxy deployment not ready" + kubectl get pods -n konflux-ui + echo "failed" > /shared/port-forward-status + exit 1 + } + + echo "✓ Deployment is ready" + + # Get service and pod info + kubectl get svc proxy -n konflux-ui -o wide + echo "" + + # Get pod name + POD_NAME=$(kubectl get pod -n konflux-ui -l app=proxy -o jsonpath='{.items[0].metadata.name}') + if [[ -z "${POD_NAME}" ]]; then + echo "ERROR: Could not find proxy pod" + kubectl get pods -n konflux-ui + echo "failed" > /shared/port-forward-status + exit 1 + fi + + echo "Found pod: ${POD_NAME}" + echo "" + + # Get detailed pod information + echo "=== Pod Details ===" + kubectl get pod ${POD_NAME} -n konflux-ui -o wide + echo "" + + echo "=== Container Ports Configuration ===" + kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{range .spec.containers[*]}Container: {.name}{"\n"}{range .ports[*]} - {.name}: {.containerPort}/{.protocol}{"\n"}{end}{"\n"}{end}' + echo "" + + # Get nginx container ports + NGINX_HTTP_PORT=$(kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{.spec.containers[?(@.name=="nginx")].ports[?(@.name=="web")].containerPort}') + NGINX_HTTPS_PORT=$(kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{.spec.containers[?(@.name=="nginx")].ports[?(@.name=="web-tls")].containerPort}') + + echo "Nginx HTTP port (web): ${NGINX_HTTP_PORT}" + echo "Nginx HTTPS port (web-tls): ${NGINX_HTTPS_PORT}" + echo "" + + # Check what's actually listening inside the pod + echo "=== Checking Listening Ports in Pod ===" + echo "Running 'ss -tln' in nginx container:" + kubectl exec ${POD_NAME} -n konflux-ui -c nginx -- ss -tln 2>/dev/null | grep LISTEN || echo "Could not run ss" + echo "" + + echo "Running 'ss -tln' in oauth2-proxy container:" + kubectl exec ${POD_NAME} -n konflux-ui -c oauth2-proxy -- ss -tln 2>/dev/null | grep LISTEN || echo "Could not run ss" + echo "" + + # Test connectivity from within the cluster + echo "=== Testing Pod Connectivity from Cluster ===" + POD_IP=$(kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{.status.podIP}') + echo "Pod IP: ${POD_IP}" + + echo "Testing HTTP to pod IP:${NGINX_HTTP_PORT}..." + HTTP_TEST=$(timeout 5 kubectl exec ${POD_NAME} -n konflux-ui -c nginx -- curl -s -o /dev/null -w "%{http_code}" http://localhost:${NGINX_HTTP_PORT} 2>&1 || echo "failed") + echo " Result: ${HTTP_TEST}" + + echo "Testing HTTPS to pod IP:${NGINX_HTTPS_PORT}..." + HTTPS_TEST=$(timeout 5 kubectl exec ${POD_NAME} -n konflux-ui -c nginx -- curl -k -s -o /dev/null -w "%{http_code}" https://localhost:${NGINX_HTTPS_PORT} 2>&1 || echo "failed") + echo " Result: ${HTTPS_TEST}" + echo "" + + # Start port forward to nginx container's HTTPS port (9443) + # We use HTTPS because nginx definitely listens on 9443 + echo "==========================================" + echo "STARTING PORT FORWARD" + echo "==========================================" + echo "Command: kubectl port-forward -n konflux-ui pod/${POD_NAME} 8080:${NGINX_HTTPS_PORT}" + echo "This will forward:" + echo " localhost:8080 (in this sidecar) -> pod ${POD_NAME}:${NGINX_HTTPS_PORT} (nginx HTTPS)" + echo "" + echo "Port forward starting in background..." + + # Start port-forward in background + kubectl port-forward -n konflux-ui pod/${POD_NAME} 8080:${NGINX_HTTPS_PORT} & + PF_PID=$! + + echo "Port-forward process started with PID: ${PF_PID}" + + # Wait for port-forward to be ready + echo "Waiting for port-forward to be ready..." + MAX_WAIT=30 + ELAPSED=0 + while [[ ${ELAPSED} -lt ${MAX_WAIT} ]]; do + # Use HTTPS with -k to ignore cert, since we're forwarding to port 9443 (HTTPS) + HTTP_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" https://localhost:8080 2>/dev/null || echo "000") + echo " Attempt $((ELAPSED + 1)): HTTP code = ${HTTP_CODE}" + if echo "${HTTP_CODE}" | grep -qE "^(200|301|302|304|401|403|404)$"; then + echo "✓ Port-forward is ready!" + break + fi + sleep 1 + ELAPSED=$((ELAPSED + 1)) + done + + if [[ ${ELAPSED} -ge ${MAX_WAIT} ]]; then + echo "ERROR: Port-forward not ready after ${MAX_WAIT}s" + echo "Last HTTP code: ${HTTP_CODE}" + echo "failed" > /shared/port-forward-status + exit 1 + fi + + # Signal that port-forward is ready + echo "ready" > /shared/port-forward-status + echo "✓ Readiness marker created at /shared/port-forward-status" + + # Keep sidecar alive by waiting for the port-forward process + echo "Port-forward is running. Waiting for process to complete..." + wait $PF_PID + steps: + - name: run-e2e-test + image: quay.io/konflux_ui_qe/konflux-ui-tests:latest + workingDir: /tmp/e2e + volumeMounts: + - name: shared-data + mountPath: /shared + env: + - name: JOB_SPEC + value: $(params.job-spec) + - name: JOB_TYPE + value: $(params.job-type) + - name: CYPRESS_LOCAL_CLUSTER + value: "true" + - name: CYPRESS_PERIODIC_RUN_STAGE + value: "false" + - name: CYPRESS_USERNAME + valueFrom: + secretKeyRef: + name: $(params.cypress-credentials-secret) + key: username + - name: CYPRESS_PASSWORD + valueFrom: + secretKeyRef: + name: $(params.cypress-credentials-secret) + key: password + - name: CYPRESS_GH_TOKEN + valueFrom: + secretKeyRef: + name: $(params.github-credentials-secret) + key: token + - name: CYPRESS_PROJECT_ID + valueFrom: + secretKeyRef: + name: $(params.cypress-cloud-secret) + key: project-id + optional: true + - name: CYPRESS_RECORD_KEY + valueFrom: + secretKeyRef: + name: $(params.cypress-cloud-secret) + key: record-key + optional: true + script: | + #!/usr/bin/env bash + set -euo pipefail + + echo "==========================================" + echo "STEP-RUN-E2E-TEST" + echo "==========================================" + echo "=== Running Cypress E2E Tests ===" + echo "Job Type: ${JOB_TYPE}" + echo "" + echo "=== DEBUG: Task Parameters ===" + echo "Parameters received by this step:" + echo " JOB_TYPE: ${JOB_TYPE}" + echo " CYPRESS_LOCAL_CLUSTER: ${CYPRESS_LOCAL_CLUSTER}" + echo " CYPRESS_PERIODIC_RUN_STAGE: ${CYPRESS_PERIODIC_RUN_STAGE}" + echo "" + echo "Note: cluster-access-secret is used by the port-forward sidecar" + echo " Check sidecar logs for parameter passing details" + echo "" + + # Verify CYPRESS_GH_TOKEN + if [[ -z "${CYPRESS_GH_TOKEN:-}" ]]; then + echo "ERROR: CYPRESS_GH_TOKEN is not set!" + exit 1 + fi + echo "✓ CYPRESS_GH_TOKEN is set (length: ${#CYPRESS_GH_TOKEN})" + echo "" + + # Configure based on job type + if [[ ${JOB_TYPE} == 'periodic-stage' ]]; then + echo "Running against stage environment..." + export CYPRESS_LOCAL_CLUSTER=false + export CYPRESS_PERIODIC_RUN_STAGE=true + else + echo "Running against local Kind cluster..." + + # Wait for port-forward sidecar to be ready using shared marker file + echo "=== Waiting for port-forward sidecar ===" + echo "Checking for readiness marker at /shared/port-forward-status..." + echo "" + MAX_WAIT=60 + ELAPSED=0 + + while [[ ${ELAPSED} -lt ${MAX_WAIT} ]]; do + if [[ -f /shared/port-forward-status ]]; then + STATUS=$(cat /shared/port-forward-status) + echo "Status file found! Content: '${STATUS}'" + if [[ "${STATUS}" == "ready" ]]; then + echo "✓ Port-forward sidecar is ready!" + break + elif [[ "${STATUS}" == "failed" ]]; then + echo "" + echo "==========================================" + echo "ERROR: Port-forward sidecar FAILED" + echo "==========================================" + echo "" + echo "The port-forward sidecar reported a failure." + echo "Check the 'port-forward' sidecar logs for details:" + echo "" + echo " kubectl logs -c port-forward -n " + echo "" + echo "Common issues:" + echo " 1. cluster-access-secret parameter is empty or not passed" + echo " 2. Secret doesn't exist in the namespace" + echo " 3. Secret exists but missing 'kubeconfig' key" + echo " 4. Deployment not ready (timeout waiting for proxy deployment)" + echo "" + exit 1 + elif [[ "${STATUS}" == "skipped" ]]; then + echo "ERROR: Port-forward was skipped but required for local cluster" + echo "This should only happen for periodic-stage jobs." + exit 1 + else + echo "Unknown status: '${STATUS}' - continuing to wait..." + fi + fi + echo "Waiting for port-forward readiness (${ELAPSED}s/${MAX_WAIT}s)..." + sleep 2 + ELAPSED=$((ELAPSED + 2)) + done + + if [[ ${ELAPSED} -ge ${MAX_WAIT} ]]; then + echo "" + echo "==========================================" + echo "ERROR: Port-forward not ready after ${MAX_WAIT}s" + echo "==========================================" + echo "" + echo "Status file check:" + if [[ -f /shared/port-forward-status ]]; then + echo " Status file exists with content: '$(cat /shared/port-forward-status)'" + else + echo " ✗ Status file NOT FOUND at /shared/port-forward-status" + echo "" + echo "This means the port-forward sidecar never wrote the status file." + echo "Possible causes:" + echo " 1. Sidecar is still initializing" + echo " 2. Sidecar failed before writing status (check sidecar logs)" + echo " 3. Shared volume mount issue" + echo "" + echo "Check sidecar logs:" + echo " kubectl logs -c port-forward -n " + fi + echo "" + exit 1 + fi + echo "" + + # Port-forward maps localhost:8080 to nginx HTTPS port (9443) + export CYPRESS_KONFLUX_BASE_URL="https://localhost:8080" + fi + + # Run tests + SPEC_FILE="tests/basic-happy-path.spec.ts" + echo "" + echo "Running: ${SPEC_FILE}" + echo "CYPRESS_KONFLUX_BASE_URL: ${CYPRESS_KONFLUX_BASE_URL:-not set}" + echo "CYPRESS_LOCAL_CLUSTER: ${CYPRESS_LOCAL_CLUSTER}" + echo "CYPRESS_PERIODIC_RUN_STAGE: ${CYPRESS_PERIODIC_RUN_STAGE}" + echo "" + + # Build Cypress command with optional recording + CYPRESS_ARGS="--runner-ui -b chrome --spec ${SPEC_FILE}" + + if [[ -n "${CYPRESS_PROJECT_ID:-}" && -n "${CYPRESS_RECORD_KEY:-}" ]]; then + echo "✓ Cypress Cloud recording enabled" + echo " Project ID: ${CYPRESS_PROJECT_ID}" + CYPRESS_ARGS="${CYPRESS_ARGS} --record" + + # Add tag if JOB_TYPE is set and not empty + if [[ -n "${JOB_TYPE:-}" ]]; then + CYPRESS_ARGS="${CYPRESS_ARGS} --tag ${JOB_TYPE}" + echo " Tag: ${JOB_TYPE}" + fi + else + echo "ℹ Cypress Cloud recording disabled (PROJECT_ID or RECORD_KEY not set)" + fi + + echo "Running: npx cypress run ${CYPRESS_ARGS}" + npx cypress run ${CYPRESS_ARGS} || EXIT_CODE=$? + + EXIT_CODE=${EXIT_CODE:-0} + echo ${EXIT_CODE} > /tmp/e2e-exit-code + + # Show artifact locations + echo "" + echo "==========================================" + echo "TEST ARTIFACTS SUMMARY" + echo "==========================================" + + if [[ -d /tmp/e2e/cypress ]]; then + echo "" + echo "Artifacts available at:" + echo " Location: /tmp/e2e/cypress" + echo "" + + if ls /tmp/e2e/cypress/videos/*.mp4 >/dev/null 2>&1; then + echo "Videos:" + ls -lh /tmp/e2e/cypress/videos/ + echo "" + fi + + if [[ -d /tmp/e2e/cypress/screenshots ]] && [[ -n "$(ls -A /tmp/e2e/cypress/screenshots 2>/dev/null)" ]]; then + echo "Screenshots:" + find /tmp/e2e/cypress/screenshots -type f + echo "" + fi + + if [[ -f /tmp/e2e/cypress/index.html ]]; then + echo "HTML Report:" + echo " /tmp/e2e/cypress/index.html" + echo "" + fi + fi + + # Debug pause for manual artifact inspection + DEBUG_PAUSE=$(params.debug-pause-minutes) + if [[ "${DEBUG_PAUSE}" != "0" ]] && [[ -n "${DEBUG_PAUSE}" ]]; then + PAUSE_SECONDS=$((DEBUG_PAUSE * 60)) + + echo "==========================================" + echo "DEBUG PAUSE ACTIVATED" + echo "==========================================" + echo "" + echo "Pod will remain alive for ${DEBUG_PAUSE} minute(s)" + echo "" + echo "To download artifacts, run:" + echo "" + echo " # Get this pod name" + echo " POD_NAME=\$(kubectl get pods -n wlin-tenant -l tekton.dev/taskRun --field-selector status.phase=Running -o jsonpath='{.items[0].metadata.name}')" + echo "" + echo " # Download all artifacts" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress ./cypress-artifacts -c run-e2e-test" + echo "" + echo " # Download video only" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress/videos ./videos -c run-e2e-test" + echo "" + echo " # Download screenshots only" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress/screenshots ./screenshots -c run-e2e-test" + echo "" + echo " # Download HTML report" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress/index.html ./test-report.html -c run-e2e-test" + echo "" + echo "Pausing now..." + echo "" + + # Countdown with status updates + REMAINING=${PAUSE_SECONDS} + while [[ ${REMAINING} -gt 0 ]]; do + MINS=$((REMAINING / 60)) + SECS=$((REMAINING % 60)) + echo "⏳ Time remaining: ${MINS}m ${SECS}s (Cancel PipelineRun to exit early)" + sleep 60 + REMAINING=$((REMAINING - 60)) + done + + echo "" + echo "Debug pause complete. Continuing..." + fi + + exit ${EXIT_CODE} + + - name: upload-artifacts-to-oci + image: quay.io/konflux-ci/oras:latest + workingDir: /tmp/e2e + env: + - name: OCI_STORAGE + value: $(params.oci-storage) + - name: GIT_REVISION + value: $(params.git-revision) + - name: JOB_TYPE + value: $(params.job-type) + - name: REGISTRY_AUTH_FILE + value: /secrets/.dockerconfigjson + - name: PIPELINE_RUN_NAME + valueFrom: + fieldRef: + fieldPath: metadata.labels['tekton.dev/pipelineRun'] + volumeMounts: + - name: oci-credentials + mountPath: /secrets + readOnly: true + script: | + #!/usr/bin/env bash + set -euo pipefail + + # Skip if OCI storage not configured + if [[ -z "${OCI_STORAGE}" || "${OCI_STORAGE}" == "" ]]; then + echo "ℹ OCI storage not configured, skipping artifact upload" + exit 0 + fi + + echo "==========================================" + echo "UPLOADING ARTIFACTS TO OCI REGISTRY" + echo "==========================================" + echo "" + + # Check if artifacts exist + if [[ ! -d /tmp/e2e/cypress ]]; then + echo "⚠ No artifacts found at /tmp/e2e/cypress" + exit 0 + fi + + # Verify authentication + if [[ ! -f "${REGISTRY_AUTH_FILE}" ]]; then + echo "ERROR: Registry auth file not found at ${REGISTRY_AUTH_FILE}" + echo "Make sure the secret '$(params.oci-credentials-secret)' exists and contains '.dockerconfigjson' key" + exit 1 + fi + + echo "✓ Registry authentication file found" + echo "" + + # Generate unique tag based on git revision and timestamp + SHORT_SHA="${GIT_REVISION:0:7}" + TIMESTAMP=$(date -u +%Y%m%d-%H%M%S) + + # Build the full OCI reference with tag + # Remove any existing tag from OCI_STORAGE base + OCI_BASE="${OCI_STORAGE%%:*}" + + # Create unique tag: - + TAG="${SHORT_SHA}-${TIMESTAMP}" + OCI_REF="${OCI_BASE}:${TAG}" + + echo "Configuration:" + echo " Base repository: ${OCI_BASE}" + echo " Tag: ${TAG}" + echo " Full reference: ${OCI_REF}" + echo " Git revision: ${GIT_REVISION}" + echo " Job type: ${JOB_TYPE}" + echo " PipelineRun: ${PIPELINE_RUN_NAME:-N/A}" + echo "" + + cd /tmp/e2e/cypress + + # Create a tarball of all artifacts + TARBALL="/tmp/cypress-artifacts.tar.gz" + echo "Creating tarball of artifacts..." + tar czf "${TARBALL}" . 2>/dev/null || { + echo "ERROR: Failed to create tarball" + exit 1 + } + + if [[ ! -f "${TARBALL}" ]]; then + echo "ERROR: Tarball was not created" + exit 1 + fi + + TARBALL_SIZE=$(du -h "${TARBALL}" | cut -f1) + echo "✓ Tarball created: ${TARBALL_SIZE}" + echo "" + + # Prepare annotations with metadata + CREATED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ) + + echo "Uploading to OCI registry..." + echo "Command: oras push ${OCI_REF}" + echo "" + + # Upload using oras with rich annotations + oras push "${OCI_REF}" \ + "${TARBALL}:application/gzip" \ + --annotation "org.opencontainers.image.title=cypress-e2e-artifacts" \ + --annotation "org.opencontainers.image.description=Cypress test artifacts (videos, screenshots, reports)" \ + --annotation "org.opencontainers.image.created=${CREATED_AT}" \ + --annotation "org.opencontainers.image.revision=${GIT_REVISION}" \ + --annotation "dev.konflux.job-type=${JOB_TYPE}" \ + --annotation "dev.konflux.pipeline-run=${PIPELINE_RUN_NAME:-unknown}" \ + --annotation "dev.konflux.artifact-type=cypress-test-results" || { + echo "" + echo "ERROR: Failed to push artifacts to OCI registry" + echo "This might be due to:" + echo " 1. Invalid credentials in secret '$(params.oci-credentials-secret)'" + echo " 2. Insufficient permissions to push to ${OCI_BASE}" + echo " 3. Network connectivity issues" + echo "" + echo "To verify credentials:" + echo " oc get secret $(params.oci-credentials-secret) -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq" + echo "" + exit 1 + } + + echo "" + echo "==========================================" + echo "✓ ARTIFACTS UPLOADED SUCCESSFULLY" + echo "==========================================" + echo "" + echo "Artifact Details:" + echo " Repository: ${OCI_BASE}" + echo " Tag: ${TAG}" + echo " Full reference: ${OCI_REF}" + echo " Size: ${TARBALL_SIZE}" + echo " Created: ${CREATED_AT}" + echo "" + echo "To download and extract artifacts:" + echo " oras pull ${OCI_REF}" + echo " tar xzf cypress-artifacts.tar.gz" + echo "" + echo "To view in browser:" + echo " https://quay.io/repository/konflux_ui_qe/pr-check-artefacts?tab=tags" + echo "" + + - name: report-to-slack + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 + env: + - name: JOB_TYPE + value: $(params.job-type) + - name: SLACK_TOKEN + valueFrom: + secretKeyRef: + name: $(params.slack-credentials-secret) + key: token + optional: true + - name: SLACK_CHANNEL_ID + valueFrom: + configMapKeyRef: + name: slack-config + key: channel-id + optional: true + - name: PIPELINE_RUN_NAME + valueFrom: + fieldRef: + fieldPath: metadata.labels['tekton.dev/pipelineRun'] + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + script: | + #!/usr/bin/env bash + + # Only send Slack report for periodic jobs + if [[ ! ${JOB_TYPE} == periodic* ]]; then + echo "Not a periodic job (JOB_TYPE=${JOB_TYPE}), skipping Slack report" + exit 0 + fi + + # Check if Slack is configured + if [[ -z "${SLACK_TOKEN}" || -z "${SLACK_CHANNEL_ID}" ]]; then + echo "Slack not configured, skipping report" + exit 0 + fi + + # Determine test outcome + E2E_OUTCOME="success" + if [[ -f /tmp/e2e-exit-code ]] && [[ $(cat /tmp/e2e-exit-code) -ne 0 ]]; then + E2E_OUTCOME="failure" + fi + + # Generate message + if [[ $E2E_OUTCOME == "success" ]]; then + ICON=":white_check_mark:" + else + ICON=":x:" + fi + + DATE_STR=$(date '+%b %-d') + + case "$JOB_TYPE" in + "periodic-local") + JOB_DESC="LOCAL Periodic job" + ;; + "periodic-stage") + JOB_DESC="STAGE Periodic job" + ;; + "periodic-cleanup") + JOB_DESC="CLEANUP Periodic job" + ;; + *) + JOB_DESC="Periodic job (${JOB_TYPE})" + ;; + esac + + # Add PipelineRun info to message + if [[ -n "${PIPELINE_RUN_NAME}" ]]; then + MESSAGE="${ICON} Report ${DATE_STR}: ${JOB_DESC} (PipelineRun: ${PIPELINE_RUN_NAME})" + else + MESSAGE="${ICON} Report ${DATE_STR}: ${JOB_DESC}" + fi + + echo "Sending Slack notification: ${MESSAGE}" + + # Send to Slack + curl -X POST https://slack.com/api/chat.postMessage \ + -H "Authorization: Bearer ${SLACK_TOKEN}" \ + -H "Content-Type: application/json; charset=utf-8" \ + -d "{\"channel\": \"${SLACK_CHANNEL_ID}\", \"text\": \"${MESSAGE}\"}" \ + || echo "Failed to send Slack notification (non-fatal)" diff --git a/integration-tests/Tasks/run-e2e-konflux-ui.yaml.debug-backup b/integration-tests/Tasks/run-e2e-konflux-ui.yaml.debug-backup new file mode 100644 index 00000000..52b3614d --- /dev/null +++ b/integration-tests/Tasks/run-e2e-konflux-ui.yaml.debug-backup @@ -0,0 +1,856 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: run-e2e-konflux-ui + annotations: + tekton.dev/displayName: 'konflux-ui-e2e-tests' + tekton.dev/categories: 'Pipeline' + tekton.dev/tags: 'e2e,cypress,konflux-ui' +spec: + description: >- + Runs E2E tests for Konflux UI using Cypress + params: + - name: job-spec + description: 'Job specification metadata' + type: string + - name: job-type + description: 'Type of job (e.g., periodic-stage, periodic, pr)' + type: string + default: "pr-check" + - name: git-url + description: 'Git repository URL' + type: string + - name: git-revision + description: 'Git revision to checkout' + type: string + default: "main" + - name: cypress-credentials-secret + description: 'Secret name containing Cypress credentials (username, password)' + type: string + default: "cypress-credentials" + - name: slack-credentials-secret + description: 'Secret name containing Slack credentials' + type: string + default: "slack-credentials" + - name: github-credentials-secret + description: 'Secret name containing GitHub token' + type: string + default: "github-credentials" + - name: cluster-access-secret + description: 'Secret name containing kubeconfig for accessing Kind cluster' + type: string + default: "" + - name: cypress-cloud-secret + description: 'Secret name containing Cypress Cloud credentials (project-id, record-key)' + type: string + default: "cypress-cloud-credentials" + - name: debug-pause-minutes + description: 'Minutes to pause after test for artifact inspection (0 to skip, max 60)' + type: string + default: "0" + - name: oci-storage + description: 'OCI repository to store test artifacts (e.g., quay.io/user/repo:tag)' + type: string + default: "" + - name: oci-credentials-secret + description: 'Secret containing OCI registry credentials' + type: string + default: "quay-secret" + results: + - name: e2e-output + description: 'Result of e2e test' + volumes: + - name: kubeconfig + secret: + secretName: $(params.cluster-access-secret) + optional: true + - name: shared-data + emptyDir: {} + - name: oci-credentials + secret: + secretName: $(params.oci-credentials-secret) + optional: true + items: + - key: .dockerconfigjson + path: .dockerconfigjson + sidecars: + - name: port-forward + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 + volumeMounts: + - name: kubeconfig + mountPath: /credentials + - name: shared-data + mountPath: /shared + env: + - name: JOB_TYPE + value: $(params.job-type) + - name: CLUSTER_ACCESS_SECRET_PARAM + value: $(params.cluster-access-secret) + script: | + #!/usr/bin/env bash + set -euo pipefail + + echo "==========================================" + echo "PORT FORWARD SIDECAR - DEBUG INFO" + echo "==========================================" + echo "" + echo "Environment:" + echo " JOB_TYPE: ${JOB_TYPE}" + echo "" + echo "Task Parameters Received:" + echo " cluster-access-secret (from param): $(params.cluster-access-secret)" + echo " cluster-access-secret (from env): ${CLUSTER_ACCESS_SECRET_PARAM}" + echo "" + echo "IMPORTANT: If the above shows empty string, the parameter was not passed from Pipeline!" + echo "" + + echo "=== Checking /credentials directory ===" + if [[ -d /credentials ]]; then + echo "✓ Directory exists. Contents:" + ls -laR /credentials/ || echo "Cannot list /credentials" + echo "" + echo "File count: $(find /credentials -type f 2>/dev/null | wc -l)" + echo "Total size: $(du -sh /credentials 2>/dev/null | cut -f1)" + else + echo "✗ ERROR: /credentials directory does not exist!" + echo "This means the volume was not mounted at all." + fi + echo "" + + echo "=== Checking kubeconfig file ===" + if [[ -f /credentials/kubeconfig ]]; then + echo "✓ Found /credentials/kubeconfig" + ls -lh /credentials/kubeconfig + echo "File size: $(wc -c < /credentials/kubeconfig) bytes" + echo "First 5 lines:" + head -5 /credentials/kubeconfig || echo "Cannot read file" + else + echo "✗ /credentials/kubeconfig NOT FOUND" + echo "" + echo "=== Troubleshooting Info ===" + echo "" + echo "1. Checking what files exist in /credentials:" + if [[ -d /credentials ]]; then + FILE_COUNT=$(find /credentials -type f 2>/dev/null | wc -l) + echo " Found ${FILE_COUNT} file(s):" + find /credentials -type f 2>/dev/null | while read f; do + echo " - $f (size: $(stat -c%s "$f" 2>/dev/null || echo "unknown") bytes)" + done + else + echo " /credentials directory does not exist" + fi + echo "" + echo "2. Checking volume mount configuration:" + echo " Expected secret name: ${CLUSTER_ACCESS_SECRET_PARAM}" + echo " Expected key in secret: kubeconfig" + echo " Mount path: /credentials" + echo "" + echo "3. Attempting to list secrets in current namespace:" + # Try to use default service account token + if [[ -f /var/run/secrets/kubernetes.io/serviceaccount/token ]]; then + NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) + echo " Current namespace: ${NAMESPACE}" + TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) + CA_CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + + echo "" + echo " Secrets matching 'kfg-*' in namespace ${NAMESPACE}:" + SECRET_LIST=$(curl -s --cacert ${CA_CERT} -H "Authorization: Bearer ${TOKEN}" \ + "https://kubernetes.default.svc/api/v1/namespaces/${NAMESPACE}/secrets" \ + | grep -o '"name":"kfg-[^"]*"' | cut -d'"' -f4 || echo "") + if [[ -n "${SECRET_LIST}" ]]; then + echo "${SECRET_LIST}" | while read secret; do + echo " - ${secret}" + done + else + echo " No secrets starting with 'kfg-' found" + fi + + echo "" + echo " Checking if the specified secret exists:" + if [[ -n "${CLUSTER_ACCESS_SECRET_PARAM}" ]]; then + SECRET_EXISTS=$(curl -s --cacert ${CA_CERT} -H "Authorization: Bearer ${TOKEN}" \ + "https://kubernetes.default.svc/api/v1/namespaces/${NAMESPACE}/secrets/${CLUSTER_ACCESS_SECRET_PARAM}" \ + | grep -o '"name":"[^"]*"' | cut -d'"' -f4 || echo "") + if [[ -n "${SECRET_EXISTS}" ]]; then + echo " ✓ Secret '${CLUSTER_ACCESS_SECRET_PARAM}' EXISTS in namespace ${NAMESPACE}" + else + echo " ✗ Secret '${CLUSTER_ACCESS_SECRET_PARAM}' NOT FOUND in namespace ${NAMESPACE}" + fi + else + echo " Cannot check - cluster-access-secret parameter is empty!" + fi + else + echo " No service account token available - cannot list secrets" + fi + fi + echo "" + + # Skip port forwarding for periodic-stage jobs + if [[ "${JOB_TYPE}" == "periodic-stage" ]]; then + echo "INFO: Skipping port forward for periodic-stage job" + echo "skipped" > /shared/port-forward-status + sleep infinity + exit 0 + fi + + # Check if kubeconfig exists + if [[ ! -f /credentials/kubeconfig ]]; then + echo "==========================================" + echo "ERROR: Cannot proceed without kubeconfig" + echo "==========================================" + echo "" + echo "ROOT CAUSE ANALYSIS:" + echo "" + if [[ -z "${CLUSTER_ACCESS_SECRET_PARAM}" ]]; then + echo "✗ CRITICAL: The 'cluster-access-secret' parameter is EMPTY!" + echo "" + echo "This means the Pipeline did not pass the parameter to the Task." + echo "" + echo "Verify in Pipeline YAML that the parameter is correctly mapped:" + echo " - Pipeline parameter: 'cluster-kubeconfig-secret'" + echo " - Task parameter: 'cluster-access-secret'" + echo " - Expected mapping in Pipeline taskRef:" + echo " params:" + echo " - name: cluster-access-secret" + echo " value: '\$(params.cluster-kubeconfig-secret)'" + else + echo "Parameter 'cluster-access-secret' = '${CLUSTER_ACCESS_SECRET_PARAM}'" + echo "" + echo "The parameter is set, but the kubeconfig file is missing." + echo "Possible causes:" + echo "" + echo " 1. Secret '${CLUSTER_ACCESS_SECRET_PARAM}' doesn't exist in the namespace" + echo " 2. Secret exists but doesn't have a 'kubeconfig' key" + echo " 3. Volume mount failed (check pod events)" + echo "" + echo "Manual verification steps:" + echo " # Check if secret exists" + echo " kubectl get secret ${CLUSTER_ACCESS_SECRET_PARAM} -n " + echo "" + echo " # Check secret keys" + echo " kubectl get secret ${CLUSTER_ACCESS_SECRET_PARAM} -n -o jsonpath='{.data}' | jq 'keys'" + echo "" + echo " # Verify kubeconfig key exists and has data" + echo " kubectl get secret ${CLUSTER_ACCESS_SECRET_PARAM} -n -o jsonpath='{.data.kubeconfig}' | base64 -d | head -5" + fi + echo "" + echo "See detailed troubleshooting info above for more details." + echo "" + echo "failed" > /shared/port-forward-status + sleep infinity + exit 1 + fi + + export KUBECONFIG=/credentials/kubeconfig + echo "✓ KUBECONFIG set to: ${KUBECONFIG}" + echo "" + + echo "=== Port Forward Sidecar Starting ===" + echo "Waiting for Konflux UI deployment to be ready..." + + # Wait for deployment + kubectl wait --for=condition=available --timeout=300s deployment/proxy -n konflux-ui || { + echo "ERROR: Konflux UI proxy deployment not ready" + kubectl get pods -n konflux-ui + echo "failed" > /shared/port-forward-status + exit 1 + } + + echo "✓ Deployment is ready" + + # Get service and pod info + kubectl get svc proxy -n konflux-ui -o wide + echo "" + + # Get pod name + POD_NAME=$(kubectl get pod -n konflux-ui -l app=proxy -o jsonpath='{.items[0].metadata.name}') + if [[ -z "${POD_NAME}" ]]; then + echo "ERROR: Could not find proxy pod" + kubectl get pods -n konflux-ui + echo "failed" > /shared/port-forward-status + exit 1 + fi + + echo "Found pod: ${POD_NAME}" + echo "" + + # Get detailed pod information + echo "=== Pod Details ===" + kubectl get pod ${POD_NAME} -n konflux-ui -o wide + echo "" + + echo "=== Container Ports Configuration ===" + kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{range .spec.containers[*]}Container: {.name}{"\n"}{range .ports[*]} - {.name}: {.containerPort}/{.protocol}{"\n"}{end}{"\n"}{end}' + echo "" + + # Get nginx container ports + NGINX_HTTP_PORT=$(kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{.spec.containers[?(@.name=="nginx")].ports[?(@.name=="web")].containerPort}') + NGINX_HTTPS_PORT=$(kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{.spec.containers[?(@.name=="nginx")].ports[?(@.name=="web-tls")].containerPort}') + + echo "Nginx HTTP port (web): ${NGINX_HTTP_PORT}" + echo "Nginx HTTPS port (web-tls): ${NGINX_HTTPS_PORT}" + echo "" + + # Check what's actually listening inside the pod + echo "=== Checking Listening Ports in Pod ===" + echo "Running 'ss -tln' in nginx container:" + kubectl exec ${POD_NAME} -n konflux-ui -c nginx -- ss -tln 2>/dev/null | grep LISTEN || echo "Could not run ss" + echo "" + + echo "Running 'ss -tln' in oauth2-proxy container:" + kubectl exec ${POD_NAME} -n konflux-ui -c oauth2-proxy -- ss -tln 2>/dev/null | grep LISTEN || echo "Could not run ss" + echo "" + + # Test connectivity from within the cluster + echo "=== Testing Pod Connectivity from Cluster ===" + POD_IP=$(kubectl get pod ${POD_NAME} -n konflux-ui -o jsonpath='{.status.podIP}') + echo "Pod IP: ${POD_IP}" + + echo "Testing HTTP to pod IP:${NGINX_HTTP_PORT}..." + HTTP_TEST=$(timeout 5 kubectl exec ${POD_NAME} -n konflux-ui -c nginx -- curl -s -o /dev/null -w "%{http_code}" http://localhost:${NGINX_HTTP_PORT} 2>&1 || echo "failed") + echo " Result: ${HTTP_TEST}" + + echo "Testing HTTPS to pod IP:${NGINX_HTTPS_PORT}..." + HTTPS_TEST=$(timeout 5 kubectl exec ${POD_NAME} -n konflux-ui -c nginx -- curl -k -s -o /dev/null -w "%{http_code}" https://localhost:${NGINX_HTTPS_PORT} 2>&1 || echo "failed") + echo " Result: ${HTTPS_TEST}" + echo "" + + # Start port forward to nginx container's HTTPS port (9443) + # We use HTTPS because nginx definitely listens on 9443 + echo "==========================================" + echo "STARTING PORT FORWARD" + echo "==========================================" + echo "Command: kubectl port-forward -n konflux-ui pod/${POD_NAME} 8080:${NGINX_HTTPS_PORT}" + echo "This will forward:" + echo " localhost:8080 (in this sidecar) -> pod ${POD_NAME}:${NGINX_HTTPS_PORT} (nginx HTTPS)" + echo "" + echo "Port forward starting in background..." + + # Start port-forward in background + kubectl port-forward -n konflux-ui pod/${POD_NAME} 8080:${NGINX_HTTPS_PORT} & + PF_PID=$! + + echo "Port-forward process started with PID: ${PF_PID}" + + # Wait for port-forward to be ready + echo "Waiting for port-forward to be ready..." + MAX_WAIT=30 + ELAPSED=0 + while [[ ${ELAPSED} -lt ${MAX_WAIT} ]]; do + # Use HTTPS with -k to ignore cert, since we're forwarding to port 9443 (HTTPS) + HTTP_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" https://localhost:8080 2>/dev/null || echo "000") + echo " Attempt $((ELAPSED + 1)): HTTP code = ${HTTP_CODE}" + if echo "${HTTP_CODE}" | grep -qE "^(200|301|302|304|401|403|404)$"; then + echo "✓ Port-forward is ready!" + break + fi + sleep 1 + ELAPSED=$((ELAPSED + 1)) + done + + if [[ ${ELAPSED} -ge ${MAX_WAIT} ]]; then + echo "ERROR: Port-forward not ready after ${MAX_WAIT}s" + echo "Last HTTP code: ${HTTP_CODE}" + echo "failed" > /shared/port-forward-status + exit 1 + fi + + # Signal that port-forward is ready + echo "ready" > /shared/port-forward-status + echo "✓ Readiness marker created at /shared/port-forward-status" + + # Keep sidecar alive by waiting for the port-forward process + echo "Port-forward is running. Waiting for process to complete..." + wait $PF_PID + steps: + - name: run-e2e-test + image: quay.io/konflux_ui_qe/konflux-ui-tests:latest + workingDir: /tmp/e2e + volumeMounts: + - name: shared-data + mountPath: /shared + env: + - name: JOB_SPEC + value: $(params.job-spec) + - name: JOB_TYPE + value: $(params.job-type) + - name: CYPRESS_LOCAL_CLUSTER + value: "true" + - name: CYPRESS_PERIODIC_RUN_STAGE + value: "false" + - name: CYPRESS_USERNAME + valueFrom: + secretKeyRef: + name: $(params.cypress-credentials-secret) + key: username + - name: CYPRESS_PASSWORD + valueFrom: + secretKeyRef: + name: $(params.cypress-credentials-secret) + key: password + - name: CYPRESS_GH_TOKEN + valueFrom: + secretKeyRef: + name: $(params.github-credentials-secret) + key: token + - name: CYPRESS_PROJECT_ID + valueFrom: + secretKeyRef: + name: $(params.cypress-cloud-secret) + key: project-id + optional: true + - name: CYPRESS_RECORD_KEY + valueFrom: + secretKeyRef: + name: $(params.cypress-cloud-secret) + key: record-key + optional: true + script: | + #!/usr/bin/env bash + set -euo pipefail + + echo "==========================================" + echo "STEP-RUN-E2E-TEST" + echo "==========================================" + echo "=== Running Cypress E2E Tests ===" + echo "Job Type: ${JOB_TYPE}" + echo "" + echo "=== DEBUG: Task Parameters ===" + echo "Parameters received by this step:" + echo " JOB_TYPE: ${JOB_TYPE}" + echo " CYPRESS_LOCAL_CLUSTER: ${CYPRESS_LOCAL_CLUSTER}" + echo " CYPRESS_PERIODIC_RUN_STAGE: ${CYPRESS_PERIODIC_RUN_STAGE}" + echo "" + echo "Note: cluster-access-secret is used by the port-forward sidecar" + echo " Check sidecar logs for parameter passing details" + echo "" + + # Verify CYPRESS_GH_TOKEN + if [[ -z "${CYPRESS_GH_TOKEN:-}" ]]; then + echo "ERROR: CYPRESS_GH_TOKEN is not set!" + exit 1 + fi + echo "✓ CYPRESS_GH_TOKEN is set (length: ${#CYPRESS_GH_TOKEN})" + echo "" + + # Configure based on job type + if [[ ${JOB_TYPE} == 'periodic-stage' ]]; then + echo "Running against stage environment..." + export CYPRESS_LOCAL_CLUSTER=false + export CYPRESS_PERIODIC_RUN_STAGE=true + else + echo "Running against local Kind cluster..." + + # Wait for port-forward sidecar to be ready using shared marker file + echo "=== Waiting for port-forward sidecar ===" + echo "Checking for readiness marker at /shared/port-forward-status..." + echo "" + MAX_WAIT=60 + ELAPSED=0 + + while [[ ${ELAPSED} -lt ${MAX_WAIT} ]]; do + if [[ -f /shared/port-forward-status ]]; then + STATUS=$(cat /shared/port-forward-status) + echo "Status file found! Content: '${STATUS}'" + if [[ "${STATUS}" == "ready" ]]; then + echo "✓ Port-forward sidecar is ready!" + break + elif [[ "${STATUS}" == "failed" ]]; then + echo "" + echo "==========================================" + echo "ERROR: Port-forward sidecar FAILED" + echo "==========================================" + echo "" + echo "The port-forward sidecar reported a failure." + echo "Check the 'port-forward' sidecar logs for details:" + echo "" + echo " kubectl logs -c port-forward -n " + echo "" + echo "Common issues:" + echo " 1. cluster-access-secret parameter is empty or not passed" + echo " 2. Secret doesn't exist in the namespace" + echo " 3. Secret exists but missing 'kubeconfig' key" + echo " 4. Deployment not ready (timeout waiting for proxy deployment)" + echo "" + exit 1 + elif [[ "${STATUS}" == "skipped" ]]; then + echo "ERROR: Port-forward was skipped but required for local cluster" + echo "This should only happen for periodic-stage jobs." + exit 1 + else + echo "Unknown status: '${STATUS}' - continuing to wait..." + fi + fi + echo "Waiting for port-forward readiness (${ELAPSED}s/${MAX_WAIT}s)..." + sleep 2 + ELAPSED=$((ELAPSED + 2)) + done + + if [[ ${ELAPSED} -ge ${MAX_WAIT} ]]; then + echo "" + echo "==========================================" + echo "ERROR: Port-forward not ready after ${MAX_WAIT}s" + echo "==========================================" + echo "" + echo "Status file check:" + if [[ -f /shared/port-forward-status ]]; then + echo " Status file exists with content: '$(cat /shared/port-forward-status)'" + else + echo " ✗ Status file NOT FOUND at /shared/port-forward-status" + echo "" + echo "This means the port-forward sidecar never wrote the status file." + echo "Possible causes:" + echo " 1. Sidecar is still initializing" + echo " 2. Sidecar failed before writing status (check sidecar logs)" + echo " 3. Shared volume mount issue" + echo "" + echo "Check sidecar logs:" + echo " kubectl logs -c port-forward -n " + fi + echo "" + exit 1 + fi + echo "" + + # Port-forward maps localhost:8080 to nginx HTTPS port (9443) + export CYPRESS_KONFLUX_BASE_URL="https://localhost:8080" + fi + + # Run tests + SPEC_FILE="tests/basic-happy-path.spec.ts" + echo "" + echo "Running: ${SPEC_FILE}" + echo "CYPRESS_KONFLUX_BASE_URL: ${CYPRESS_KONFLUX_BASE_URL:-not set}" + echo "CYPRESS_LOCAL_CLUSTER: ${CYPRESS_LOCAL_CLUSTER}" + echo "CYPRESS_PERIODIC_RUN_STAGE: ${CYPRESS_PERIODIC_RUN_STAGE}" + echo "" + + # Build Cypress command with optional recording + CYPRESS_ARGS="--runner-ui -b chrome --spec ${SPEC_FILE}" + + if [[ -n "${CYPRESS_PROJECT_ID:-}" && -n "${CYPRESS_RECORD_KEY:-}" ]]; then + echo "✓ Cypress Cloud recording enabled" + echo " Project ID: ${CYPRESS_PROJECT_ID}" + CYPRESS_ARGS="${CYPRESS_ARGS} --record" + + # Add tag if JOB_TYPE is set and not empty + if [[ -n "${JOB_TYPE:-}" ]]; then + CYPRESS_ARGS="${CYPRESS_ARGS} --tag ${JOB_TYPE}" + echo " Tag: ${JOB_TYPE}" + fi + else + echo "ℹ Cypress Cloud recording disabled (PROJECT_ID or RECORD_KEY not set)" + fi + + echo "Running: npx cypress run ${CYPRESS_ARGS}" + npx cypress run ${CYPRESS_ARGS} || EXIT_CODE=$? + + EXIT_CODE=${EXIT_CODE:-0} + echo ${EXIT_CODE} > /tmp/e2e-exit-code + + # Show artifact locations + echo "" + echo "==========================================" + echo "TEST ARTIFACTS SUMMARY" + echo "==========================================" + + if [[ -d /tmp/e2e/cypress ]]; then + echo "" + echo "Artifacts available at:" + echo " Location: /tmp/e2e/cypress" + echo "" + + if ls /tmp/e2e/cypress/videos/*.mp4 >/dev/null 2>&1; then + echo "Videos:" + ls -lh /tmp/e2e/cypress/videos/ + echo "" + fi + + if [[ -d /tmp/e2e/cypress/screenshots ]] && [[ -n "$(ls -A /tmp/e2e/cypress/screenshots 2>/dev/null)" ]]; then + echo "Screenshots:" + find /tmp/e2e/cypress/screenshots -type f + echo "" + fi + + if [[ -f /tmp/e2e/cypress/index.html ]]; then + echo "HTML Report:" + echo " /tmp/e2e/cypress/index.html" + echo "" + fi + fi + + # Debug pause for manual artifact inspection + DEBUG_PAUSE=$(params.debug-pause-minutes) + if [[ "${DEBUG_PAUSE}" != "0" ]] && [[ -n "${DEBUG_PAUSE}" ]]; then + PAUSE_SECONDS=$((DEBUG_PAUSE * 60)) + + echo "==========================================" + echo "DEBUG PAUSE ACTIVATED" + echo "==========================================" + echo "" + echo "Pod will remain alive for ${DEBUG_PAUSE} minute(s)" + echo "" + echo "To download artifacts, run:" + echo "" + echo " # Get this pod name" + echo " POD_NAME=\$(kubectl get pods -n wlin-tenant -l tekton.dev/taskRun --field-selector status.phase=Running -o jsonpath='{.items[0].metadata.name}')" + echo "" + echo " # Download all artifacts" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress ./cypress-artifacts -c run-e2e-test" + echo "" + echo " # Download video only" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress/videos ./videos -c run-e2e-test" + echo "" + echo " # Download screenshots only" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress/screenshots ./screenshots -c run-e2e-test" + echo "" + echo " # Download HTML report" + echo " kubectl cp wlin-tenant/\${POD_NAME}:/tmp/e2e/cypress/index.html ./test-report.html -c run-e2e-test" + echo "" + echo "Pausing now..." + echo "" + + # Countdown with status updates + REMAINING=${PAUSE_SECONDS} + while [[ ${REMAINING} -gt 0 ]]; do + MINS=$((REMAINING / 60)) + SECS=$((REMAINING % 60)) + echo "⏳ Time remaining: ${MINS}m ${SECS}s (Cancel PipelineRun to exit early)" + sleep 60 + REMAINING=$((REMAINING - 60)) + done + + echo "" + echo "Debug pause complete. Continuing..." + fi + + exit ${EXIT_CODE} + + - name: upload-artifacts-to-oci + image: quay.io/konflux-ci/oras:latest + workingDir: /tmp/e2e + env: + - name: OCI_STORAGE + value: $(params.oci-storage) + - name: GIT_REVISION + value: $(params.git-revision) + - name: JOB_TYPE + value: $(params.job-type) + - name: REGISTRY_AUTH_FILE + value: /secrets/.dockerconfigjson + - name: PIPELINE_RUN_NAME + valueFrom: + fieldRef: + fieldPath: metadata.labels['tekton.dev/pipelineRun'] + volumeMounts: + - name: oci-credentials + mountPath: /secrets + readOnly: true + script: | + #!/usr/bin/env bash + set -euo pipefail + + # Skip if OCI storage not configured + if [[ -z "${OCI_STORAGE}" || "${OCI_STORAGE}" == "" ]]; then + echo "ℹ OCI storage not configured, skipping artifact upload" + exit 0 + fi + + echo "==========================================" + echo "UPLOADING ARTIFACTS TO OCI REGISTRY" + echo "==========================================" + echo "" + + # Check if artifacts exist + if [[ ! -d /tmp/e2e/cypress ]]; then + echo "⚠ No artifacts found at /tmp/e2e/cypress" + exit 0 + fi + + # Verify authentication + if [[ ! -f "${REGISTRY_AUTH_FILE}" ]]; then + echo "ERROR: Registry auth file not found at ${REGISTRY_AUTH_FILE}" + echo "Make sure the secret '$(params.oci-credentials-secret)' exists and contains '.dockerconfigjson' key" + exit 1 + fi + + echo "✓ Registry authentication file found" + echo "" + + # Generate unique tag based on git revision and timestamp + SHORT_SHA="${GIT_REVISION:0:7}" + TIMESTAMP=$(date -u +%Y%m%d-%H%M%S) + + # Build the full OCI reference with tag + # Remove any existing tag from OCI_STORAGE base + OCI_BASE="${OCI_STORAGE%%:*}" + + # Create unique tag: - + TAG="${SHORT_SHA}-${TIMESTAMP}" + OCI_REF="${OCI_BASE}:${TAG}" + + echo "Configuration:" + echo " Base repository: ${OCI_BASE}" + echo " Tag: ${TAG}" + echo " Full reference: ${OCI_REF}" + echo " Git revision: ${GIT_REVISION}" + echo " Job type: ${JOB_TYPE}" + echo " PipelineRun: ${PIPELINE_RUN_NAME:-N/A}" + echo "" + + cd /tmp/e2e/cypress + + # Create a tarball of all artifacts + TARBALL="/tmp/cypress-artifacts.tar.gz" + echo "Creating tarball of artifacts..." + tar czf "${TARBALL}" . 2>/dev/null || { + echo "ERROR: Failed to create tarball" + exit 1 + } + + if [[ ! -f "${TARBALL}" ]]; then + echo "ERROR: Tarball was not created" + exit 1 + fi + + TARBALL_SIZE=$(du -h "${TARBALL}" | cut -f1) + echo "✓ Tarball created: ${TARBALL_SIZE}" + echo "" + + # Prepare annotations with metadata + CREATED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ) + + echo "Uploading to OCI registry..." + echo "Command: oras push ${OCI_REF}" + echo "" + + # Upload using oras with rich annotations + oras push "${OCI_REF}" \ + "${TARBALL}:application/gzip" \ + --annotation "org.opencontainers.image.title=cypress-e2e-artifacts" \ + --annotation "org.opencontainers.image.description=Cypress test artifacts (videos, screenshots, reports)" \ + --annotation "org.opencontainers.image.created=${CREATED_AT}" \ + --annotation "org.opencontainers.image.revision=${GIT_REVISION}" \ + --annotation "dev.konflux.job-type=${JOB_TYPE}" \ + --annotation "dev.konflux.pipeline-run=${PIPELINE_RUN_NAME:-unknown}" \ + --annotation "dev.konflux.artifact-type=cypress-test-results" || { + echo "" + echo "ERROR: Failed to push artifacts to OCI registry" + echo "This might be due to:" + echo " 1. Invalid credentials in secret '$(params.oci-credentials-secret)'" + echo " 2. Insufficient permissions to push to ${OCI_BASE}" + echo " 3. Network connectivity issues" + echo "" + echo "To verify credentials:" + echo " oc get secret $(params.oci-credentials-secret) -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq" + echo "" + exit 1 + } + + echo "" + echo "==========================================" + echo "✓ ARTIFACTS UPLOADED SUCCESSFULLY" + echo "==========================================" + echo "" + echo "Artifact Details:" + echo " Repository: ${OCI_BASE}" + echo " Tag: ${TAG}" + echo " Full reference: ${OCI_REF}" + echo " Size: ${TARBALL_SIZE}" + echo " Created: ${CREATED_AT}" + echo "" + echo "To download and extract artifacts:" + echo " oras pull ${OCI_REF}" + echo " tar xzf cypress-artifacts.tar.gz" + echo "" + echo "To view in browser:" + echo " https://quay.io/repository/konflux_ui_qe/pr-check-artefacts?tab=tags" + echo "" + + - name: report-to-slack + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 + env: + - name: JOB_TYPE + value: $(params.job-type) + - name: SLACK_TOKEN + valueFrom: + secretKeyRef: + name: $(params.slack-credentials-secret) + key: token + optional: true + - name: SLACK_CHANNEL_ID + valueFrom: + configMapKeyRef: + name: slack-config + key: channel-id + optional: true + - name: PIPELINE_RUN_NAME + valueFrom: + fieldRef: + fieldPath: metadata.labels['tekton.dev/pipelineRun'] + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + script: | + #!/usr/bin/env bash + + # Only send Slack report for periodic jobs + if [[ ! ${JOB_TYPE} == periodic* ]]; then + echo "Not a periodic job (JOB_TYPE=${JOB_TYPE}), skipping Slack report" + exit 0 + fi + + # Check if Slack is configured + if [[ -z "${SLACK_TOKEN}" || -z "${SLACK_CHANNEL_ID}" ]]; then + echo "Slack not configured, skipping report" + exit 0 + fi + + # Determine test outcome + E2E_OUTCOME="success" + if [[ -f /tmp/e2e-exit-code ]] && [[ $(cat /tmp/e2e-exit-code) -ne 0 ]]; then + E2E_OUTCOME="failure" + fi + + # Generate message + if [[ $E2E_OUTCOME == "success" ]]; then + ICON=":white_check_mark:" + else + ICON=":x:" + fi + + DATE_STR=$(date '+%b %-d') + + case "$JOB_TYPE" in + "periodic-local") + JOB_DESC="LOCAL Periodic job" + ;; + "periodic-stage") + JOB_DESC="STAGE Periodic job" + ;; + "periodic-cleanup") + JOB_DESC="CLEANUP Periodic job" + ;; + *) + JOB_DESC="Periodic job (${JOB_TYPE})" + ;; + esac + + # Add PipelineRun info to message + if [[ -n "${PIPELINE_RUN_NAME}" ]]; then + MESSAGE="${ICON} Report ${DATE_STR}: ${JOB_DESC} (PipelineRun: ${PIPELINE_RUN_NAME})" + else + MESSAGE="${ICON} Report ${DATE_STR}: ${JOB_DESC}" + fi + + echo "Sending Slack notification: ${MESSAGE}" + + # Send to Slack + curl -X POST https://slack.com/api/chat.postMessage \ + -H "Authorization: Bearer ${SLACK_TOKEN}" \ + -H "Content-Type: application/json; charset=utf-8" \ + -d "{\"channel\": \"${SLACK_CHANNEL_ID}\", \"text\": \"${MESSAGE}\"}" \ + || echo "Failed to send Slack notification (non-fatal)" diff --git a/integration-tests/Tasks/show-snapshot-data.yaml b/integration-tests/Tasks/show-snapshot-data.yaml new file mode 100644 index 00000000..9561c803 --- /dev/null +++ b/integration-tests/Tasks/show-snapshot-data.yaml @@ -0,0 +1,18 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: test-metadata +spec: + params: + - name: snapshot + description: 'The JSON string representing the snapshot of the application under test.' + type: string + steps: + - name: echo + image: alpine + env: + - name: SNAPSHOT + value: $(params.snapshot) + script: | + #!/bin/sh + echo "${SNAPSHOT}" diff --git a/integration-tests/test-run-e2e-task.yaml b/integration-tests/test-run-e2e-task.yaml new file mode 100644 index 00000000..5c0810df --- /dev/null +++ b/integration-tests/test-run-e2e-task.yaml @@ -0,0 +1,46 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + generateName: test-run-e2e- + namespace: wlin-tenant +spec: + taskRef: + resolver: git + params: + - name: url + value: https://github.com/testcara/konflux-ui-test + - name: revision + value: main + - name: pathInRepo + value: integration-tests/Tasks/run-e2e-konflux-ui.yaml + params: + - name: job-spec + value: | + { + "container_image": "quay.io/redhat-user-workloads-stage/wlin-tenant/cara-konflux-ui-test-b1228:latest", + "konflux_component": "cara-konflux-ui-test-b1228", + "git": { + "pull_request_number": null, + "pull_request_author": null, + "git_org": "testcara", + "git_repo": "konflux-ui-test", + "commit_sha": "f1be336", + "event_type": "push", + "source_repo_url": "https://github.com/testcara/konflux-ui-test", + "source_repo_branch": "refs/heads/main", + "target_repo_branch": "main" + } + } + - name: job-type + value: "" + - name: git-url + value: https://github.com/testcara/konflux-ui-test + - name: git-revision + value: main + - name: cypress-credentials-secret + value: cypress-credentials + - name: slack-credentials-secret + value: slack-credentials + - name: github-credentials-secret + value: github-credentials diff --git a/pr_check.sh b/pr_check.sh index 2328a6be..53b8ce65 100755 --- a/pr_check.sh +++ b/pr_check.sh @@ -7,7 +7,7 @@ export TEST_IMAGE="quay.io/konflux_ui_qe/konflux-ui-tests:latest" build_ui_image() { set -euo pipefail - + # add debug by cara echo "Building UI from commit sha ${HEAD_SHA}" export IMAGE_NAME=localhost/test/test diff --git a/src/trigger-pull-1/trigger-pull.js b/src/trigger-pull-1/trigger-pull.js new file mode 100644 index 00000000..28d79220 --- /dev/null +++ b/src/trigger-pull-1/trigger-pull.js @@ -0,0 +1,3 @@ +export const triggerPull = () => { + return 'Trigger Pull'; +}; diff --git a/src/trigger-pull/trigger-pull.js b/src/trigger-pull/trigger-pull.js new file mode 100644 index 00000000..a1cd4849 --- /dev/null +++ b/src/trigger-pull/trigger-pull.js @@ -0,0 +1,3 @@ +export const TriggerPull = () => { + return 'trigger pull'; +}; diff --git a/yarn.lock b/yarn.lock index 1e92f240..fd75cfc9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10104,9 +10104,9 @@ strip-json-comments@^3.1.1: integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strip-json-comments@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-5.0.1.tgz#0d8b7d01b23848ed7dbdf4baaaa31a8250d8cfa0" - integrity sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw== + version "5.0.3" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-5.0.3.tgz#b7304249dd402ee67fd518ada993ab3593458bcf" + integrity sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw== style-loader@^4.0.0: version "4.0.0"