diff --git a/.github/workflows/crc-e2e-builder.yaml b/.github/workflows/crc-e2e-builder.yaml new file mode 100644 index 0000000..61c5287 --- /dev/null +++ b/.github/workflows/crc-e2e-builder.yaml @@ -0,0 +1,79 @@ +name: crc-e2e-builder + +on: + push: + tags: [ 'crc-e2e-v*' ] + pull_request: + branches: [ main ] + paths: ['crc-e2e/**', '.github\/workflows\/crc-e2e*' ] + +jobs: + build: + name: build + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build image for PR + if: ${{ github.event_name == 'pull_request' }} + env: + CRC_E2E: ghcr.io/crc-org/ci-crc-e2e + CRC_E2E_V: pr-${{ github.event.number }} + run: | + make crc-e2e-oci-build + make crc-e2e-oci-save + echo "image=${CRC_E2E}:${CRC_E2E_V}" >> "$GITHUB_ENV" + + - name: Create image metadata + run: | + echo ${{ env.image }} > crc-e2e-image + echo ${{ github.event_name }} > crc-e2e-build-event + + - name: Upload crc-e2e + uses: actions/upload-artifact@v4 + with: + name: crc-e2e + path: crc-e2e* + + tkn-check: + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Template tkn for PR + if: ${{ github.event_name == 'pull_request' }} + env: + CRC_E2E: ghcr.io/crc-org/ci-crc-e2e + CRC_E2E_V: pr-${{ github.event.number }} + run: | + make crc-e2e-tkn-create + + - name: Check tkn specs + run: | + if [[ ! -f crc-e2e/tkn/crc-e2e-installer.yaml ]]; then + exit 1 + fi + if [[ ! -f crc-e2e/tkn/crc-e2e.yaml ]]; then + exit 1 + fi + # Check if version is in sync + + - name: Create k8s Kind Cluster + uses: helm/kind-action@v1 + + # https://docs.openshift.com/pipelines/1.15/about/op-release-notes.html + - name: Deploy min supported tekton version + run: kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.44.5/release.yaml + + - name: Deploy tasks + run: | + kubectl apply -f crc-e2e/tkn/crc-e2e-installer.yaml + kubectl apply -f crc-e2e/tkn/crc-e2e.yaml + + - name: Upload crc-e2e-tkn + uses: actions/upload-artifact@v4 + with: + name: crc-e2e-tkn + path: crc-e2e/tkn/crc-e2e* diff --git a/.github/workflows/crc-e2e-pusher.yaml b/.github/workflows/crc-e2e-pusher.yaml new file mode 100644 index 0000000..42f7caf --- /dev/null +++ b/.github/workflows/crc-e2e-pusher.yaml @@ -0,0 +1,71 @@ +name: crc-e2e-pusher + +on: + workflow_run: + workflows: crc-e2e-builder + types: + - completed + +jobs: + push: + name: push + if: ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + steps: + - name: Download crc-e2e assets + uses: actions/download-artifact@v4 + with: + name: crc-e2e + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} + + - name: Get crc-e2e build informaiton + run: | + echo "source_event=$(cat crc-e2e-build-event)" >> "$GITHUB_ENV" + echo "image=$(cat crc-e2e-image)" >> "$GITHUB_ENV" + + - name: Log in to ghcr.io + if: ${{ env.source_event == 'pull_request' }} + uses: redhat-actions/podman-login@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log in quay.io + if: ${{ env.source_event == 'push' }} + uses: redhat-actions/podman-login@v1 + with: + registry: quay.io + username: ${{ secrets.QUAY_IO_USERNAME }} + password: ${{ secrets.QUAY_IO_PASSWORD }} + + - name: Push crc-e2e + run: | + podman load -i crc-e2e-linux.tar + podman push ${{ env.image }}-linux + podman load -i crc-e2e-windows.tar + podman push ${{ env.image }}-windows + podman load -i crc-e2e-darwin.tar + podman push ${{ env.image }}-darwin + + - name: Download crc-e2e-tkn assets + uses: actions/download-artifact@v4 + with: + name: crc-e2e-tkn + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} + + - name: Push crc-e2e-tkn + env: + TKN_VERSION: '0.37.0' + run: | + curl -LO "https://github.com/tektoncd/cli/releases/download/v${TKN_VERSION}/tkn_${TKN_VERSION}_Linux_x86_64.tar.gz" + tar xvzf "tkn_${TKN_VERSION}_Linux_x86_64.tar.gz" tkn + ./tkn bundle push ${{ env.image }}-tkn \ + -f crc-e2e-installer.yaml \ + -f crc-e2e.yaml + diff --git a/Makefile b/Makefile index 89c58a2..f187299 100644 --- a/Makefile +++ b/Makefile @@ -107,4 +107,22 @@ endif -f crc-builder/tkn/crc-builder-installer.yaml \ -f crc-builder/tkn/crc-builder.yaml \ -f crc-builder/tkn/crc-builder-arm64.yaml - \ No newline at end of file + +#### crc-e2e #### + +.PHONY: crc-e2e-tkn-create crc-e2e-tkn-push + +# Registries and versions +CRC_E2E ?= $(shell sed -n 1p crc-e2e/release-info) +CRC_E2E_V ?= v$(shell sed -n 2p crc-e2e/release-info) +CRC_E2E_SAVE ?= crc-e2e + +crc-e2e-tkn-create: + $(call tkn_template,$(CRC_E2E),$(CRC_E2E_V),crc-e2e,crc-e2e) + +crc-e2e-tkn-push: install-out-of-tree-tools +ifndef IMAGE + IMAGE = $(CRC_E2E):$(CRC_E2E_V) +endif + $(TOOLS_BINDIR)/tkn bundle push $(IMAGE)-tkn \ + -f crc-e2e/tkn/crc-e2e.yaml diff --git a/crc-e2e/CHANGELOG.md b/crc-e2e/CHANGELOG.md new file mode 100644 index 0000000..f295773 --- /dev/null +++ b/crc-e2e/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 1.0.0 + +* Initial version diff --git a/crc-e2e/README.md b/crc-e2e/README.md new file mode 100644 index 0000000..e047c34 --- /dev/null +++ b/crc-e2e/README.md @@ -0,0 +1,35 @@ +# CRC e2e + +## Modifications to the image + +Changes to `crc-e2e/os/macos/builder/build.sh` require re-building and pushing the image to internal registry (ImageStream). Make sure the changes are pushed to some `mybranch` on your fork of the QE platform repo (`github.com//qe-platform`). Since the `crc-e2e/manifests/buildconfig.yaml` will be guiding the build of the image, it needs to specify your branch on your fork as the source. + +```diff + source: + contextDir: support/images/crc-e2e + git: + # dev ++ ref: 'mybranch' ++ uri: 'https://gitlab.cee.redhat.com//qe-platform.git' +- ref: v2.14.0 +- uri: 'https://gitlab.cee.redhat.com/crc/qe-platform.git' + type: Git +``` + +Log in to `codeready-container` project, apply the changes in `crc-e2e/manifests/buildconfig.yaml` and start the build from the corresponding `BuildConfig` (depending on the platform). + +```bash +oc apply -f support/images/crc-e2e/manifests/buildconfig.yaml +oc start-build image-crc-e2e- +``` + +Lastly, make sure that `imagePullPolicy` is set to `Always` in all places that use this imageStreamTag (e.g. `crc-e2e:v0.0.3-macos`). In our case, we needed to change and re-apply the following YAML. + +```bash +oc apply -f orchestrator/catalog/task/crc-e2e-installer/0.3/crc-e2e-installer.yaml +``` + +Then undo changes to `crc-e2e/manifests/buildconfig.yaml` so it points to the upstream repository. + +_If everything works as expected, send an MR to `gitlab.cee.redhat.com/crc/qe-platform`._ + diff --git a/crc-e2e/release-info b/crc-e2e/release-info new file mode 100644 index 0000000..537c057 --- /dev/null +++ b/crc-e2e/release-info @@ -0,0 +1,2 @@ +quay.io/crc-org/ci-crc-e2e +1.0.0-dev diff --git a/crc-e2e/tkn/tpl/crc-e2e.tpl.yaml b/crc-e2e/tkn/tpl/crc-e2e.tpl.yaml new file mode 100644 index 0000000..20866da --- /dev/null +++ b/crc-e2e/tkn/tpl/crc-e2e.tpl.yaml @@ -0,0 +1,261 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: crc-e2e-integration-test + labels: + app.kubernetes.io/version: "cversion" + redhat.com/product: openshift-local + dev.lifecycle.io/phase: testing + annotations: + tekton.dev/pipelines.minVersion: "0.44.x" + tekton.dev/categories: openshift-local + tekton.dev/tags: openshift-local, testing + tekton.dev/displayName: "testing for openshift local" + tekton.dev/platforms: "linux/amd64" +spec: + description: >- + This task will run qe testing on an openshift local instance running on a remote target host. + + This task run set of tests of choice: integration or e2e or both. Or even allow to run specific + scenarios based on tags + + params: + # correlate params + - name: workspace-resources-path + description: path on workspace to find resources to connect and managed provisioned machine + # target platform /arch params + - name: os + description: type of platform per target host (linux, windows, macos) + default: linux + - name: arch + description: type of arch (amd64, arm64). Defaults amd64 + default: amd64 + # remote target host params + - name: host + description: target host + - name: username + description: username to connect to the provisioned machine + - name: key + description: key file name to connect to the provisioned machine within the workspace resources path + # crc params + - name: crc-version + description: crc version to be tested (i.e 2.34.1) + # default: latest + - name: bundle-location + description: custom bundle already downloaded on the target host. + default: "''" + # control params + - name: cleanup-home + description: control whether to remove crc home folder before runing e2e suite + default: 'false' + - name: run-e2e + description: Control if e2e tests are executed. (true or false) + default: 'true' + - name: e2e-tag + description: tags to select e2e scnearios. Default empty values which means all scnearios + default: "''" + - name: e2e-junit-name + description: set the name for the junit results file for e2e + default: e2e-junit.xml + - name: e2e-custom-memory + description: If we want to customize the base memory to run the e2e we can set this value + default: "''" + - name: e2e-cleanup-target + description: To cleanup remote folder after running e2e + default: "true" + - name: run-integration + description: Control if integration tests are executed. (true or false) + default: 'true' + - name: integration-tag + description: tags to select integration scenarios. Default empty values which means all scnearios + default: "''" + - name: integration-timeout + description: total timeout for run integration suite + default: "90m" + - name: integration-junit-name + description: set the name for the junit results file for integration + default: integration-junit.xml + - name: integration-cleanup-target + description: To cleanup remote folder after running integration + default: "true" + - name: worspace-qe-subpath + description: subpath relative to workspace path where results are stored + default: qe-results + - name: debug + description: debug purposes extend verbosity on cmds executed on the target + default: 'false' + + results: + - name: e2e-duration + description: total amount of time in seconds for the e2e execution + - name: integration-duration + description: total amount of time in seconds for the integration execution + + steps: + - name: e2e + # cimage and cversion values should be passed to the template + image: cimage:cversion-$(params.os)-$(params.arch) + imagePullPolicy: Always + env: + - name: OUTPUT_FOLDER + value: $(workspaces.pipelines-data.path)/$(params.workspace-resources-path)/$(params.worspace-qe-subpath) + script: | + #!/bin/bash + + set pipefail + + # If debug add verbosity + if [[ $(params.debug) == "true" ]]; then + set -exuo pipefail + fi + + if [[ $(params.run-e2e) == "true" ]]; then + # Prepare ENVs + SECONDS=0 + DEBUG=$(params.debug) + TARGET_HOST=$(params.host) + TARGET_HOST_USERNAME=$(params.username) + TARGET_HOST_KEY_PATH=$(workspaces.pipelines-data.path)/$(params.workspace-resources-path)/$(params.key) + chmod 600 ${TARGET_HOST_KEY_PATH} + TARGET_FOLDER=crc-e2e + TARGET_RESULTS=results + TARGET_CLEANUP=$(params.e2e-cleanup-target) + # Create output folder + mkdir -p "${OUTPUT_FOLDER}" + + # Pull secret (if exists) + if test -f /etc/crc/pullsecret; then + # ASSETS_FOLDER ENV is defined at Containerfile + # All assets inside that folder will be copied to the target host + cp /etc/crc/pullsecret ${ASSETS_FOLDER}/pull-secret + fi + + # Create cmd per OS + runner="run.sh" + if [[ $(params.os) == "windows" ]]; then + runner="run.ps1" + fi + cmd="${TARGET_FOLDER}/${runner} -targetFolder ${TARGET_FOLDER} " + cmd="$cmd -junitFilename $(params.e2e-junit-name) " + if [[ $(params.bundle-location) != "" ]]; then + cmd="$cmd -bundleLocation $(params.bundle-location) " + fi + if [[ $(params.e2e-tag) != "" ]]; then + cmd="$cmd -e2eTagExpression '$(params.e2e-tag)' " + fi + if [[ $(params.e2e-custom-memory) != "" ]]; then + cmd="$cmd -crcMemory $(params.e2e-custom-memory) " + fi + + # Exec + . entrypoint.sh "${cmd}" + + # Move all results to qe-path + mv ${OUTPUT_FOLDER}/${TARGET_RESULTS}/* ${OUTPUT_FOLDER} + rm -rf ${OUTPUT_FOLDER}/${TARGET_RESULTS} + + echo -n "${SECONDS}" | tee $(results.e2e-duration.path) + fi + resources: + requests: + memory: "50Mi" + cpu: "5m" + limits: + memory: "70Mi" + cpu: "10m" + - name: clean-config + image: quay.io/rhqp/deliverest:v0.0.7 + script: | + #!/bin/sh + + if [[ $(params.run-e2e) == "true" ]]; then + ssh -i $(workspaces.pipelines-data.path)/$(params.workspace-resources-path)/$(params.key) \ + -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + $(params.username)@$(params.host) 'rm ~/.crc/crc.json' | true + fi + - name: integration + image: quay.io/crcont/crc-integration:v$(params.crc-version)-$(params.os)-$(params.arch) + imagePullPolicy: Always + env: + - name: OUTPUT_FOLDER + value: $(workspaces.pipelines-data.path)/$(params.workspace-resources-path)/$(params.worspace-qe-subpath) + script: | + #!/bin/sh + + set pipefail + + # If debug add verbosity + if [[ $(params.debug) == "true" ]]; then + set -exuo pipefail + fi + + if [[ $(params.run-integration) == "true" ]]; then + # Prepare ENVs + SECONDS=0 + DEBUG=$(params.debug) + TARGET_HOST=$(params.host) + TARGET_HOST_USERNAME=$(params.username) + TARGET_HOST_KEY_PATH=$(workspaces.pipelines-data.path)/$(params.workspace-resources-path)/$(params.key) + chmod 600 ${TARGET_HOST_KEY_PATH} + TARGET_FOLDER=crc-integration + TARGET_RESULTS=results + TARGET_CLEANUP=$(params.integration-cleanup-target) + # Create output folder + mkdir -p "${OUTPUT_FOLDER}" + + # Pull secret (if exists) + if test -f /etc/crc/pullsecret; then + # ASSETS_FOLDER ENV is defined at Containerfile + # All assets inside that folder will be copied to the target host + cp /etc/crc/pullsecret ${ASSETS_FOLDER}/pull-secret + fi + + # Create cmd per OS + runner="run.sh" + if [[ $(params.os) == "windows" ]]; then + runner="run.ps1" + fi + cmd="${TARGET_FOLDER}/${runner} -targetFolder ${TARGET_FOLDER} " + cmd="$cmd -junitFilename $(params.integration-junit-name) " + cmd="$cmd -suiteTimeout $(params.integration-timeout) " + if [[ $(params.bundle-location) != "" ]]; then + cmd="$cmd -bundleLocation $(params.bundle-location) " + fi + if [[ "$(params.integration-tag)" != "" ]]; then + cmd="$cmd -labelFilter '$(params.integration-tag)' " + fi + + # Exec + . entrypoint.sh "${cmd}" + + # Move all results to qe-path + mv ${OUTPUT_FOLDER}/${TARGET_RESULTS}/* ${OUTPUT_FOLDER} + rm -rf ${OUTPUT_FOLDER}/${TARGET_RESULTS} + + echo -n "${SECONDS}" | tee $(results.integration-duration.path) + fi + resources: + requests: + memory: "50Mi" + cpu: "5m" + limits: + memory: "70Mi" + cpu: "10m" + + workspaces: + - name: pipelines-data + - name: ocp-pullsecret + description: | + crc secret name holding the pullsecret. This is only required if backed tested is crc preset + + secret should match following format: + --- + apiVersion: v1 + kind: Secret + metadata: + name: ${secret-name} + type: Opaque + data: + pullsecret: ${pullsecret-value} + mountPath: /etc/crc