From 677168fef85daf83257c5082681e533e8fd4c846 Mon Sep 17 00:00:00 2001 From: Viet Nguyen Duc Date: Tue, 23 Apr 2024 07:06:49 +0000 Subject: [PATCH] [build][doc]: build images with combination Grid and browser versions (#2218) --- NodeChrome/Dockerfile | 5 +- NodeEdge/Dockerfile | 11 +- README.md | 29 ++++ tag_and_push_browser_images.sh | 6 + tests/build-backward-compatible/bootstrap.sh | 66 ++++++++ tests/build-backward-compatible/builder.py | 48 ++++++ .../build-backward-compatible/cdp-matrix.yml | 58 +++++++ .../selenium-matrix.yml | 148 ++++++++++++++++++ 8 files changed, 368 insertions(+), 3 deletions(-) create mode 100755 tests/build-backward-compatible/bootstrap.sh create mode 100755 tests/build-backward-compatible/builder.py create mode 100644 tests/build-backward-compatible/cdp-matrix.yml create mode 100644 tests/build-backward-compatible/selenium-matrix.yml diff --git a/NodeChrome/Dockerfile b/NodeChrome/Dockerfile index 41f4c57ef..52bba5e43 100644 --- a/NodeChrome/Dockerfile +++ b/NodeChrome/Dockerfile @@ -19,9 +19,10 @@ ARG TARGETARCH=amd64 RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor | tee /etc/apt/trusted.gpg.d/google.gpg >/dev/null \ && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list \ && apt-get update -qqy \ - && if echo "${CHROME_VERSION}" | grep -qE "google-chrome-stable_[0-9]*"; \ + && if echo "${CHROME_VERSION}" | grep -qE "google-chrome-stable[_|=][0-9]*"; \ then \ - wget -qO google-chrome.deb "https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/${CHROME_VERSION}_${TARGETARCH}.deb" \ + CHROME_VERSION=$(echo "$CHROME_VERSION" | tr '=' '_') \ + && wget -qO google-chrome.deb "https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/${CHROME_VERSION}_${TARGETARCH}.deb" \ && apt-get -qqy --no-install-recommends install --allow-downgrades ./google-chrome.deb \ && rm -rf google-chrome.deb ; \ else \ diff --git a/NodeEdge/Dockerfile b/NodeEdge/Dockerfile index 4f6ddeb0f..a2f15c3b0 100644 --- a/NodeEdge/Dockerfile +++ b/NodeEdge/Dockerfile @@ -13,10 +13,19 @@ USER root # e.g. microsoft-edge-beta=88.0.692.0-1 #============================================ ARG EDGE_VERSION="microsoft-edge-stable" +ARG TARGETARCH=amd64 RUN wget -q -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/microsoft.gpg >/dev/null \ && echo "deb https://packages.microsoft.com/repos/edge stable main" >> /etc/apt/sources.list.d/microsoft-edge.list \ && apt-get update -qqy \ - && apt-get -qqy --no-install-recommends install ${EDGE_VERSION} \ + && if echo "${EDGE_VERSION}" | grep -qE "microsoft-edge-stable[_|=][0-9]*"; \ + then \ + EDGE_VERSION=$(echo "$EDGE_VERSION" | tr '=' '_') \ + && wget -qO microsoft-edge.deb "https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable/${EDGE_VERSION}_${TARGETARCH}.deb" \ + && apt-get -qqy --no-install-recommends install --allow-downgrades ./microsoft-edge.deb \ + && rm -rf microsoft-edge.deb ; \ + else \ + apt-get -qqy --no-install-recommends install ${EDGE_VERSION} ; \ + fi \ && rm /etc/apt/sources.list.d/microsoft-edge.list \ && rm -rf /var/lib/apt/lists/* /var/cache/apt/* diff --git a/README.md b/README.md index d43871f9c..fb970b4b7 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ Talk to us at https://www.selenium.dev/support/ * [Stopping the Node/Standalone after N sessions have been executed](#stopping-the-nodestandalone-after-n-sessions-have-been-executed) * [Automatic browser leftovers cleanup](#automatic-browser-leftovers-cleanup) * [Building the images](#building-the-images) +* [Build the images with specific versions](#build-the-images-with-specific-versions) +* [Upgrade browser version in the images](#upgrade-browser-version-in-the-images) * [Waiting for the Grid to be ready](#waiting-for-the-grid-to-be-ready) * [Adding a HEALTHCHECK to the Grid](#adding-a-healthcheck-to-the-grid) * [Using a bash script to wait for the Grid](#using-a-bash-script-to-wait-for-the-grid) @@ -1027,6 +1029,33 @@ $ BUILD_ARGS="--build-arg SEL_USER=yourseluser --build-arg SEL_PASSWD=welcome" m ``` ___ +# Build the images with specific versions + +Based on the latest Dockerfile (by cloning the repo and from the project directory root), you can build the images with a specific combination of Selenium Grid, and browser versions. + +For example, you would like to build `node-chrome` and `standalone-chrome` images with the Grid based version `4.17.0`, Chrome browser versions `119`, `120`, `123` respectively. + +```bash +$ ./tests/build-backward-compatible/bootstrap.sh 4.17.0 119,120,123 chrome +``` + +In generic, the script takes the following arguments: +- `$1` (mandatory): Selenium Grid version. Details are fetching from matrix [file](tests/build-backward-compatible/selenium-matrix.yml) +- `$2` (mandatory): Browser major version, multiple values separated by comma. Details are fetching from matrix [file](tests/build-backward-compatible/cdp-matrix.yml) +- `$3` (optional): browser name. If not provided, it will iterate over all the browsers (`chrome`, `edge`, `firefox`) +- `$4` (optional): Push image to registry. By default, it is `false`. If you want to push the image to the registry, set it to `true` (required Docker login to your namespace done before running the script). + +To set your namespace for the images, you can set the environment variable `NAME` before running the script. For example: + +```bash +$ export NAME=artifactory.yourcompany.com/selenium +$ ./tests/build-backward-compatible/bootstrap.sh 4.17.0 119,120,123 chrome +``` + +After running the script, you will see list images with a full tag to pin specific Grid and browser version following [Tagging Conventions](https://github.com/SeleniumHQ/docker-selenium/wiki/Tagging-Convention) + +--- + ## Upgrade browser version in the images Selenium server, browser and driver are pre-installed in the image. In case you would like to remain on the same Selenium version and just upgrade the browser and its driver to the latest. You can follow below steps diff --git a/tag_and_push_browser_images.sh b/tag_and_push_browser_images.sh index 2f14e15e9..e58689f9d 100755 --- a/tag_and_push_browser_images.sh +++ b/tag_and_push_browser_images.sh @@ -57,6 +57,8 @@ chrome) do docker tag ${NAMESPACE}/node-chrome:${TAG_VERSION} ${NAMESPACE}/node-chrome:${chrome_tag} docker tag ${NAMESPACE}/standalone-chrome:${TAG_VERSION} ${NAMESPACE}/standalone-chrome:${chrome_tag} + echo "Tagged ${NAMESPACE}/node-chrome:${chrome_tag}" + echo "Tagged ${NAMESPACE}/standalone-chrome:${chrome_tag}" if [ "${PUSH_IMAGE}" = true ]; then docker push ${NAMESPACE}/node-chrome:${chrome_tag} docker push ${NAMESPACE}/standalone-chrome:${chrome_tag} @@ -101,6 +103,8 @@ edge) do docker tag ${NAMESPACE}/node-edge:${TAG_VERSION} ${NAMESPACE}/node-edge:${edge_tag} docker tag ${NAMESPACE}/standalone-edge:${TAG_VERSION} ${NAMESPACE}/standalone-edge:${edge_tag} + echo "Tagged ${NAMESPACE}/node-edge:${edge_tag}" + echo "Tagged ${NAMESPACE}/standalone-edge:${edge_tag}" if [ "${PUSH_IMAGE}" = true ]; then docker push ${NAMESPACE}/node-edge:${edge_tag} docker push ${NAMESPACE}/standalone-edge:${edge_tag} @@ -144,6 +148,8 @@ firefox) do docker tag ${NAMESPACE}/node-firefox:${TAG_VERSION} ${NAMESPACE}/node-firefox:${firefox_tag} docker tag ${NAMESPACE}/standalone-firefox:${TAG_VERSION} ${NAMESPACE}/standalone-firefox:${firefox_tag} + echo "Tagged ${NAMESPACE}/node-firefox:${firefox_tag}" + echo "Tagged ${NAMESPACE}/standalone-firefox:${firefox_tag}" if [ "${PUSH_IMAGE}" = true ]; then docker push ${NAMESPACE}/node-firefox:${firefox_tag} docker push ${NAMESPACE}/standalone-firefox:${firefox_tag} diff --git a/tests/build-backward-compatible/bootstrap.sh b/tests/build-backward-compatible/bootstrap.sh new file mode 100755 index 000000000..1a65eb5b2 --- /dev/null +++ b/tests/build-backward-compatible/bootstrap.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +cd tests || true + +if [ "${CI:-false}" = "false" ]; then + pip3 install virtualenv | grep -v 'Requirement already satisfied' + virtualenv docker-selenium-tests + source docker-selenium-tests/bin/activate +fi + +python -m pip install pyyaml==6.0.1 \ + | grep -v 'Requirement already satisfied' + +cd .. + +SELENIUM_VERSION=$1 +CDP_VERSIONS=$2 +BROWSER=${3:-"all"} +PUSH_IMAGE=${4:-"false"} + +IFS=',' read -ra VERSION_LIST <<< "$CDP_VERSIONS" + +for CDP_VERSION in "${VERSION_LIST[@]}"; do + python tests/build-backward-compatible/builder.py ${SELENIUM_VERSION} ${CDP_VERSION} + export $(cat .env | xargs) + if [ "${BROWSER}" = "all" ] || [ "${BROWSER}" = "firefox" ]; then + if [ -n "${FIREFOX_VERSION}" ]; then + BUILD_ARGS="--build-arg FIREFOX_VERSION=${FIREFOX_VERSION}" + BUILD_ARGS="${BUILD_ARGS}" make standalone_firefox + else + echo "Firefox version not found in matrix for input ${CDP_VERSION}" + exit 1 + fi + fi + if [ "${BROWSER}" = "all" ] || [ "${BROWSER}" = "edge" ]; then + if [ -n "${EDGE_VERSION}" ]; then + BUILD_ARGS="--build-arg EDGE_VERSION=${EDGE_VERSION}" + BUILD_ARGS="${BUILD_ARGS}" make standalone_edge + else + echo "Edge version not found in matrix for input ${CDP_VERSION}" + exit 1 + fi + fi + if [ "${BROWSER}" = "all" ] || [ "${BROWSER}" = "chrome" ]; then + if [ -n "${CHROME_VERSION}" ]; then + BUILD_ARGS="--build-arg CHROME_VERSION=${CHROME_VERSION}" + BUILD_ARGS="${BUILD_ARGS}" make standalone_chrome + else + echo "Chrome version not found in matrix for input ${CDP_VERSION}" + exit 1 + fi + fi + if [ "${BROWSER}" = "all" ] || [ "${BROWSER}" = "firefox" ]; then + TAG_LOG_OUTPUT="$TAG_LOG_OUTPUT $(PUSH_IMAGE=${PUSH_IMAGE} make tag_and_push_firefox_images)" + fi + if [ "${BROWSER}" = "all" ] || [ "${BROWSER}" = "edge" ]; then + TAG_LOG_OUTPUT="$TAG_LOG_OUTPUT $(PUSH_IMAGE=${PUSH_IMAGE} make tag_and_push_edge_images)" + fi + if [ "${BROWSER}" = "all" ] || [ "${BROWSER}" = "chrome" ]; then + TAG_LOG_OUTPUT="$TAG_LOG_OUTPUT $(PUSH_IMAGE=${PUSH_IMAGE} make tag_and_push_chrome_images)" + fi +done + +readarray -t LOG_LINES <<< "$TAG_LOG_OUTPUT" +for line in "${LOG_LINES[@]}"; do + echo "$line" +done diff --git a/tests/build-backward-compatible/builder.py b/tests/build-backward-compatible/builder.py new file mode 100755 index 000000000..7778c4459 --- /dev/null +++ b/tests/build-backward-compatible/builder.py @@ -0,0 +1,48 @@ +import yaml +import sys +import logging + +logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s") +logger = logging.getLogger(__name__) + +def load_template(yaml_file): + try: + with open(yaml_file, 'r') as file: + documents = yaml.safe_load(file) + return documents + except yaml.YAMLError as error: + logger.debug("Error in configuration file: ", error) + +def recursive_merge(dict1, dict2): + for key in dict2: + if key in dict1 and isinstance(dict1[key], dict) and isinstance(dict2[key], dict): + recursive_merge(dict1[key], dict2[key]) + else: + dict1[key] = dict2[key] + +if __name__ == '__main__': + # Load matrix configuration + selenium_matrix = load_template('tests/build-backward-compatible/selenium-matrix.yml') + cdp_matrix = load_template('tests/build-backward-compatible/cdp-matrix.yml') + # Merge configurations into single matrix + recursive_merge(selenium_matrix, cdp_matrix) + matrix = selenium_matrix["matrix"] + # Get versions from arguments + selenium_version = sys.argv[1] + cdp_version = int(sys.argv[2]) + # Create .env with component versions + BASE_RELEASE = matrix["selenium"][selenium_version]["BASE_RELEASE"] + BASE_VERSION = matrix["selenium"][selenium_version]["BASE_VERSION"] + VERSION = matrix["selenium"][selenium_version]["VERSION"] + BINDING_VERSION = matrix["selenium"][selenium_version]["BINDING_VERSION"] + FIREFOX_VERSION = matrix["CDP"][cdp_version]["FIREFOX_VERSION"] + EDGE_VERSION = matrix["CDP"][cdp_version]["EDGE_VERSION"] + CHROME_VERSION = matrix["CDP"][cdp_version]["CHROME_VERSION"] + with open('.env', 'w') as f: + f.write(f"BASE_RELEASE={BASE_RELEASE}\n") + f.write(f"BASE_VERSION={BASE_VERSION}\n") + f.write(f"VERSION={VERSION}\n") + f.write(f"BINDING_VERSION={BINDING_VERSION}\n") + f.write(f"FIREFOX_VERSION={FIREFOX_VERSION}\n") + f.write(f"EDGE_VERSION={EDGE_VERSION}\n") + f.write(f"CHROME_VERSION={CHROME_VERSION}") diff --git a/tests/build-backward-compatible/cdp-matrix.yml b/tests/build-backward-compatible/cdp-matrix.yml new file mode 100644 index 000000000..ea96289d7 --- /dev/null +++ b/tests/build-backward-compatible/cdp-matrix.yml @@ -0,0 +1,58 @@ +matrix: + # List of versions get from + # Edge: https://packages.microsoft.com/repos/edge/pool/main/m/microsoft-edge-stable + # Chrome: https://www.ubuntuupdates.org/package/google_chrome/stable/main/base/google-chrome-stable + # Firefox: https://download-installer.cdn.mozilla.net/pub/firefox/releases + CDP: + 124: + EDGE_VERSION: 'microsoft-edge-stable=124.0.2478.51-1' + CHROME_VERSION: 'google-chrome-stable=124.0.6367.60-1' + FIREFOX_VERSION: '124.0.2' + 123: + EDGE_VERSION: 'microsoft-edge-stable=123.0.2420.97-1' + CHROME_VERSION: 'google-chrome-stable=123.0.6312.122-1' + FIREFOX_VERSION: '123.0.1' + 122: + EDGE_VERSION: 'microsoft-edge-stable=122.0.2365.92-1' + CHROME_VERSION: 'google-chrome-stable=122.0.6261.128-1' + FIREFOX_VERSION: '122.0.1' + 121: + EDGE_VERSION: 'microsoft-edge-stable=121.0.2277.98-1' + CHROME_VERSION: 'google-chrome-stable=121.0.6167.184-1' + FIREFOX_VERSION: '121.0.1' + 120: + EDGE_VERSION: 'microsoft-edge-stable=120.0.2210.91-1' + CHROME_VERSION: 'google-chrome-stable=120.0.6099.224-1' + FIREFOX_VERSION: '120.0.1' + 119: + EDGE_VERSION: 'microsoft-edge-stable=119.0.2151.97-1' + CHROME_VERSION: 'google-chrome-stable=119.0.6045.199-1' + FIREFOX_VERSION: '119.0.1' + 118: + EDGE_VERSION: 'microsoft-edge-stable=118.0.2088.76-1' + CHROME_VERSION: 'google-chrome-stable=118.0.5993.117-1' + FIREFOX_VERSION: '118.0.2' + 117: + EDGE_VERSION: 'microsoft-edge-stable=117.0.2045.55-1' + CHROME_VERSION: 'google-chrome-stable=117.0.5938.149-1' + FIREFOX_VERSION: '117.0.1' + 116: + EDGE_VERSION: 'microsoft-edge-stable=116.0.1938.81-1' + CHROME_VERSION: 'google-chrome-stable=116.0.5845.187-1' + FIREFOX_VERSION: '116.0.3' + 115: + EDGE_VERSION: 'microsoft-edge-stable=115.0.1901.203-1' + CHROME_VERSION: 'google-chrome-stable=115.0.5790.170-1' + FIREFOX_VERSION: '115.0.3' + 114: + EDGE_VERSION: 'microsoft-edge-stable=114.0.1823.82-1' + CHROME_VERSION: 'google-chrome-stable=114.0.5735.198-1' + FIREFOX_VERSION: '114.0.2' + 113: + EDGE_VERSION: 'microsoft-edge-stable=113.0.1774.57-1' + CHROME_VERSION: 'google-chrome-stable=113.0.5672.126-1' + FIREFOX_VERSION: '113.0.2' + 112: + EDGE_VERSION: 'microsoft-edge-stable=112.0.1722.64-1' + CHROME_VERSION: 'google-chrome-stable=112.0.5615.165-1' + FIREFOX_VERSION: '112.0.2' diff --git a/tests/build-backward-compatible/selenium-matrix.yml b/tests/build-backward-compatible/selenium-matrix.yml new file mode 100644 index 000000000..14aaa4161 --- /dev/null +++ b/tests/build-backward-compatible/selenium-matrix.yml @@ -0,0 +1,148 @@ +matrix: + # List CDP versions get from release notes https://www.selenium.dev/categories/releases/ + # https://github.com/SeleniumHQ/selenium/releases + selenium: + nightly: + BASE_RELEASE: nightly + BASE_VERSION: 4.20.0-SNAPSHOT + VERSION: 4.20.0-SNAPSHOT + BINDING_VERSION: nightly + CDP: + - 124 + - 123 + - 122 + 4.19.1: + BASE_RELEASE: selenium-4.19.0 + BASE_VERSION: 4.19.1 + VERSION: 4.19.1 + BINDING_VERSION: 4.19.0 + CDP: + - 123 + - 122 + - 121 + 4.19.0: + BASE_RELEASE: selenium-4.19.0 + BASE_VERSION: 4.19.0 + VERSION: 4.19.0 + BINDING_VERSION: 4.19.0 + CDP: + - 123 + - 122 + - 121 + 4.18.1: + BASE_RELEASE: selenium-4.18.0 + BASE_VERSION: 4.18.1 + VERSION: 4.18.1 + BINDING_VERSION: 4.18.1 + CDP: + - 122 + - 121 + - 120 + 4.18.0: + BASE_RELEASE: selenium-4.18.0 + BASE_VERSION: 4.18.0 + VERSION: 4.18.0 + BINDING_VERSION: 4.18.0 + CDP: + - 122 + - 121 + - 120 + 4.17.0: + BASE_RELEASE: selenium-4.17.0 + BASE_VERSION: 4.17.0 + VERSION: 4.17.0 + BINDING_VERSION: 4.17.2 + CDP: + - 121 + - 120 + - 119 + 4.16.1: + BASE_RELEASE: selenium-4.16.0 + BASE_VERSION: 4.16.1 + VERSION: 4.16.1 + BINDING_VERSION: 4.16.0 + CDP: + - 120 + - 119 + - 118 + 4.16.0: + BASE_RELEASE: selenium-4.16.0 + BASE_VERSION: 4.16.0 + VERSION: 4.16.0 + BINDING_VERSION: 4.16.0 + CDP: + - 120 + - 119 + - 118 + 4.15.0: + BASE_RELEASE: selenium-4.15.0 + BASE_VERSION: 4.15.0 + VERSION: 4.15.0 + BINDING_VERSION: 4.15.2 + CDP: + - 119 + - 118 + - 117 + 4.14.1: + BASE_RELEASE: selenium-4.14.0 + BASE_VERSION: 4.14.1 + VERSION: 4.14.1 + BINDING_VERSION: 4.14.0 + CDP: + - 118 + - 117 + - 116 + 4.14.0: + BASE_RELEASE: selenium-4.14.0 + BASE_VERSION: 4.14.0 + VERSION: 4.14.0 + BINDING_VERSION: 4.14.0 + CDP: + - 118 + - 117 + - 116 + 4.13.0: + BASE_RELEASE: selenium-4.13.0 + BASE_VERSION: 4.13.0 + VERSION: 4.13.0 + BINDING_VERSION: 4.13.0 + CDP: + - 117 + - 116 + - 115 + 4.12.1: + BASE_RELEASE: selenium-4.12.0 + BASE_VERSION: 4.12.1 + VERSION: 4.12.1 + BINDING_VERSION: 4.12.0 + CDP: + - 116 + - 115 + - 114 + 4.12.0: + BASE_RELEASE: selenium-4.12.0 + BASE_VERSION: 4.12.0 + VERSION: 4.12.0 + BINDING_VERSION: 4.12.0 + CDP: + - 116 + - 115 + - 114 + 4.11.0: + BASE_RELEASE: selenium-4.11.0 + BASE_VERSION: 4.11.0 + VERSION: 4.11.0 + BINDING_VERSION: 4.11.2 + CDP: + - 115 + - 114 + - 113 + 4.10.0: + BASE_RELEASE: selenium-4.10.0 + BASE_VERSION: 4.10.0 + VERSION: 4.10.0 + BINDING_VERSION: 4.10.0 + CDP: + - 114 + - 113 + - 112