diff --git a/.github/workflows/helm-chart-release.yml b/.github/workflows/helm-chart-release.yml index 0139deaf1..460327fea 100644 --- a/.github/workflows/helm-chart-release.yml +++ b/.github/workflows/helm-chart-release.yml @@ -18,6 +18,7 @@ jobs: - name: Checkout uses: actions/checkout@main with: + persist-credentials: false fetch-depth: 0 - name: Configure Git @@ -28,6 +29,18 @@ jobs: - name: Get chart release notes (chart_release_notes.md) run: ./generate_chart_changelog.sh HEAD + - name: Commit files + run: | + git config --local user.email "selenium-ci@users.noreply.github.com" + git config --local user.name "Selenium CI Bot" + git commit -m "Update tag in docs and files" -a + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.SELENIUM_CI_TOKEN }} + branch: trunk + - name: Run chart-releaser uses: helm/chart-releaser-action@main with: diff --git a/charts/selenium-grid/README.md b/charts/selenium-grid/README.md index c2c51d092..1c8738a6f 100644 --- a/charts/selenium-grid/README.md +++ b/charts/selenium-grid/README.md @@ -225,12 +225,11 @@ By default, ingress is enabled without annotations set. If NGINX ingress control To make the user experience better, there are few annotations will be set by default if NGINX ingress controller is used. Mostly relates to timeouts and buffer sizes. -If you are not using NGINX ingress controller, you can disable these default annotations by setting `ingress.nginx` to `nil` (aka null) via Helm CLI `--set ingress.nginx=null`) or via an override-values.yaml as below: +If you are not using NGINX ingress controller, you can disable these default annotations by setting `ingress.nginx` to `nil` (aka null) via Helm CLI `--set ingress.nginx=!`) or via an override-values.yaml as below: ```yaml ingress: - nginx: - # nginx: null (alternative way) + nginx: ! ``` Similarly, if you want to disable a sub-config of `ingress.nginx`. For example: `--set ingress.nginx.proxyBuffer=null`) diff --git a/tests/charts/bootstrap.sh b/tests/charts/bootstrap.sh index e2999fe30..c401e9501 100755 --- a/tests/charts/bootstrap.sh +++ b/tests/charts/bootstrap.sh @@ -12,17 +12,33 @@ python -m pip install pyyaml==6.0.1 \ | grep -v 'Requirement already satisfied' cd .. + helm template dummy --values tests/charts/templates/render/dummy.yaml \ - --set-file 'nodeConfigMap.extraScripts.nodePreStop\.sh=tests/charts/templates/render/dummy_external.sh' \ - --set-file 'recorderConfigMap.extraScripts.video\.sh=tests/charts/templates/render/dummy_external.sh' \ - --set-file 'recorderConfigMap.extraScripts.video_graphQLQuery\.sh=tests/charts/templates/render/dummy_external.sh' \ - --set-file 'recorderConfigMap.extraScripts.newInsertScript\.sh=tests/charts/templates/render/dummy_external.sh' \ - --set-file 'uploaderConfigMap.extraScripts.upload\.sh=tests/charts/templates/render/dummy_external.sh' \ - --set-file 'uploaderConfigMap.secretFiles.upload\.conf=tests/charts/templates/render/dummy_external.sh' \ + --set-file 'nodeConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ + --set-file 'recorderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ + --set-file 'uploaderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ charts/selenium-grid > ./tests/tests/dummy_template_manifests.yaml python tests/charts/templates/test.py "./tests/tests/dummy_template_manifests.yaml" dummy -ret_code=$? +if [ $? -ne 0 ]; then + echo "Failed to validate the chart" + exit 1 +fi + +helm dependency update tests/charts/umbrella-charts +helm dependency build tests/charts/umbrella-charts + +helm template dummy --values tests/charts/templates/render/dummy_solution.yaml \ + --set-file 'selenium-grid.nodeConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ + --set-file 'selenium-grid.recorderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ + --set-file 'selenium-grid.uploaderConfigMap.extraScripts.setFromCommand\.sh=tests/charts/templates/render/dummy_external.sh' \ + tests/charts/umbrella-charts > ./tests/tests/dummy_solution_template_manifests.yaml + +python tests/charts/templates/test.py "./tests/tests/dummy_solution_template_manifests.yaml" dummy +if [ $? -ne 0 ]; then + echo "Failed to validate the umbrella chart" + exit 1 +fi if [ "${CI:-false}" = "false" ]; then deactivate diff --git a/tests/charts/templates/render/dummy.yaml b/tests/charts/templates/render/dummy.yaml index acf584ec9..6b7b5598b 100644 --- a/tests/charts/templates/render/dummy.yaml +++ b/tests/charts/templates/render/dummy.yaml @@ -31,7 +31,7 @@ ingress: proxyTimeout: 360 # Set different proxy timout proxyBuffer: # size: 512M # Keep using sub-config default - number: # Disable sub-config + number: ! # Disable sub-config annotations: # Add you own annotations nginx.ingress.kubernetes.io/use-regex: "true" # Add new key nginx.ingress.kubernetes.io/rewrite-target: /$2 @@ -87,6 +87,7 @@ videoRecorder: enabled: true uploader: enabled: true + name: s3 destinationPrefix: "s3://bucket-name" secrets: RCLONE_CONFIG_S3_TYPE: "s3" @@ -97,3 +98,21 @@ videoRecorder: RCLONE_CONFIG_S3_ACL: "private" RCLONE_CONFIG_S3_ACCESS_KEY_ID: "xxx" RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: "xxx" + +nodeConfigMap: + extraScripts: + nodeCustomTask.sh: | + #!/bin/bash + echo "This is a custom task" + +recorderConfigMap: + extraScripts: + video.sh: | + #!/bin/bash + echo "This is override script" + +uploaderConfigMap: + extraScripts: + upload.sh: | + #!/bin/bash + echo "This is override script" diff --git a/tests/charts/templates/render/dummy_solution.yaml b/tests/charts/templates/render/dummy_solution.yaml new file mode 100644 index 000000000..9512bc35b --- /dev/null +++ b/tests/charts/templates/render/dummy_solution.yaml @@ -0,0 +1,118 @@ +# This is dummy values file for chart template testing +global: + K8S_PUBLIC_IP: "10.10.10.10" + seleniumGrid: + logLevel: FINE + affinity: &affinity + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - selenium + topologyKey: "kubernetes.io/hostname" + +selenium-grid: + autoscaling: + enableWithExistingKEDA: true + scalingType: deployment + + basicAuth: + username: sysadmin + password: strongPassword + + tls: + enabled: true + generateTLS: false + + ingress: + nginx: + proxyTimeout: 360 # Set different proxy timout + proxyBuffer: + # size: 512M # Keep using sub-config default + number: ! # Disable sub-config + annotations: # Add you own annotations + nginx.ingress.kubernetes.io/use-regex: "true" # Add new key + nginx.ingress.kubernetes.io/rewrite-target: /$2 + nginx.ingress.kubernetes.io/app-root: &gridAppRoot "/selenium" + nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600" # Override default key + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" # Override default key + hostname: "" + ports: + http: 8081 + https: 8443 + paths: + - path: /selenium(/|$)(.*) + pathType: ImplementationSpecific + backend: + service: + name: '{{ ternary (include "seleniumGrid.router.fullname" $ ) (include "seleniumGrid.hub.fullname" $ ) $.Values.isolateComponents }}' + port: + number: 4444 + - path: /(/?)(session/.*/se/vnc) + pathType: ImplementationSpecific + backend: + service: + name: '{{ ternary (include "seleniumGrid.router.fullname" $ ) (include "seleniumGrid.hub.fullname" $ ) $.Values.isolateComponents }}' + port: + number: 4444 + + isolateComponents: true + + components: + subPath: *gridAppRoot + disableUI: true + router: + serviceType: NodePort + distributor: + serviceType: NodePort + eventBus: + serviceType: NodePort + sessionQueue: + serviceType: NodePort + sessionMap: + serviceType: NodePort + + chromeNode: + affinity: *affinity + + firefoxNode: + affinity: *affinity + + edgeNode: + affinity: *affinity + + videoRecorder: + enabled: true + uploader: + enabled: true + destinationPrefix: "s3://bucket-name" + secrets: + RCLONE_CONFIG_S3_TYPE: "s3" + RCLONE_CONFIG_S3_PROVIDER: "AWS" + RCLONE_CONFIG_S3_ENV_AUTH: "true" + RCLONE_CONFIG_S3_REGION: "ap-southeast-1" + RCLONE_CONFIG_S3_LOCATION_CONSTRAINT: "ap-southeast-1" + RCLONE_CONFIG_S3_ACL: "private" + RCLONE_CONFIG_S3_ACCESS_KEY_ID: "xxx" + RCLONE_CONFIG_S3_SECRET_ACCESS_KEY: "xxx" + + nodeConfigMap: + extraScripts: + nodeCustomTask.sh: | + #!/bin/bash + echo "This is a custom task" + + recorderConfigMap: + extraScripts: + video.sh: | + #!/bin/bash + echo "This is override script" + + uploaderConfigMap: + extraScripts: + upload.sh: | + #!/bin/bash + echo "This is override script" diff --git a/tests/charts/templates/test.py b/tests/charts/templates/test.py index 5ac422594..e856dac7b 100644 --- a/tests/charts/templates/test.py +++ b/tests/charts/templates/test.py @@ -135,6 +135,41 @@ def test_all_metadata_name_is_prefixed_with_release_name(self): self.assertTrue(doc['metadata']['name'].startswith(RELEASE_NAME), f"Metadata name {doc['metadata']['name']} is not prefixed with RELEASE NAME: {RELEASE_NAME}") + def test_extra_script_import_to_node_configmap(self): + resources_name = ['{0}-selenium-node-config'.format(RELEASE_NAME)] + count = 0 + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] in resources_name and doc['kind'] == 'ConfigMap': + logger.info(f"Assert default file is imported to Node ConfigMap") + self.assertTrue(doc['data']['nodeProbe.sh'] is not None) + self.assertTrue(doc['data']['nodePreStop.sh'] is not None) + self.assertTrue(doc['data']['nodeCustomTask.sh'] is not None) + self.assertTrue(doc['data']['setFromCommand.sh'] is not None) + count += 1 + self.assertEqual(count, len(resources_name), "No node config resources found") + + def test_extra_script_import_to_uploader_configmap(self): + resources_name = ['{0}-selenium-uploader-config'.format(RELEASE_NAME)] + count = 0 + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] in resources_name and doc['kind'] == 'ConfigMap': + logger.info(f"Assert extra script is imported to Uploader ConfigMap") + self.assertTrue(doc['data']['upload.sh'] is not None) + self.assertTrue(doc['data']['setFromCommand.sh'] is not None) + count += 1 + self.assertEqual(count, len(resources_name), "No uploader config resources found") + + def test_extra_script_import_to_recorder_configmap(self): + resources_name = ['{0}-selenium-recorder-config'.format(RELEASE_NAME)] + count = 0 + for doc in LIST_OF_DOCUMENTS: + if doc['metadata']['name'] in resources_name and doc['kind'] == 'ConfigMap': + logger.info(f"Assert extra script is imported to Recorder ConfigMap") + self.assertTrue(doc['data']['video.sh'] is not None) + self.assertTrue(doc['data']['setFromCommand.sh'] is not None) + count += 1 + self.assertEqual(count, len(resources_name), "No recorder config resources found") + if __name__ == '__main__': failed = False try: diff --git a/tests/charts/umbrella-charts/.gitignore b/tests/charts/umbrella-charts/.gitignore new file mode 100644 index 000000000..8d8946152 --- /dev/null +++ b/tests/charts/umbrella-charts/.gitignore @@ -0,0 +1,2 @@ +charts +Chart.lock diff --git a/tests/charts/umbrella-charts/.helmignore b/tests/charts/umbrella-charts/.helmignore new file mode 100644 index 000000000..bb20efbce --- /dev/null +++ b/tests/charts/umbrella-charts/.helmignore @@ -0,0 +1,2 @@ +.git/ +.gitignore diff --git a/tests/charts/umbrella-charts/Chart.yaml b/tests/charts/umbrella-charts/Chart.yaml new file mode 100644 index 000000000..f4b51669e --- /dev/null +++ b/tests/charts/umbrella-charts/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +name: umbrella-charts +description: A Helm chart for Umbrella Chart Test +type: application +version: 0.0.1 +appVersion: "1.0.0" +dependencies: + - name: selenium-grid + version: 0.28.1 + repository: file://../../../charts/selenium-grid diff --git a/tests/charts/umbrella-charts/templates/NOTES.txt b/tests/charts/umbrella-charts/templates/NOTES.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/charts/umbrella-charts/values.yaml b/tests/charts/umbrella-charts/values.yaml new file mode 100644 index 000000000..e69de29bb