Skip to content

Conversation

@cgoldberg
Copy link
Member

@cgoldberg cgoldberg commented Oct 27, 2025

User description

Description

This PR updates the /scripts/update_versions.sh script:

  • previously, the script assumed an incremental version update. Now you have to specify old/new Selenium versions explicitly
  • also updates CDP versions used in tests

usage:

update-versions.sh <old_version> <new_version> <old_cdp_version> <new_cdp_version>

for example, if tests are currently using Selenium 4.35 and CDP v137, and you want to upgrade to everything to use Selenium 4.38 and CDP v142, you would run:

./scripts/update_versions.sh 4.35.0 4.36.0 137 142

Note: I used perl instead of sed because it is portable (sed has different options in GNU version vs. FreeBSD/macOS), and sed messes up line endings if you run it on Windows/msys. I don't know if macOS typically has perl installed. If not, I can make it fall back to sed if this is run on that OS.

Types of changes

  • Examples/Tests

Checklist

  • I have read the contributing document.
  • I have used hugo to render the site/docs locally and I am sure it works.

PR Type

Enhancement, Tests


Description

  • Replace hardcoded version calculation with explicit old/new version parameters

  • Add validation for version format (major.minor.patch)

  • Implement CDP version replacement across example files

  • Add Ruby remote webdriver spec file to version update targets


Diagram Walkthrough

flowchart LR
  A["Script Input<br/>old_version, new_version<br/>old_cdp, new_cdp"] --> B["Validate<br/>Version Format"]
  B --> C["Replace Selenium<br/>Versions in Files"]
  C --> D["Replace CDP<br/>Versions in Examples"]
  D --> E["Install Dependencies<br/>Ruby & JavaScript"]
Loading

File Walkthrough

Relevant files
Enhancement
update-versions.sh
Refactor to explicit version parameters with CDP support 

scripts/update-versions.sh

  • Changed shebang from #!/bin/bash to #!/usr/bin/env bash for better
    portability
  • Replaced automatic version calculation with explicit parameters:
    old_version, new_version, old_cdp_version, new_cdp_version
  • Added input validation to ensure all 4 arguments are provided and
    follow major.minor.patch format
  • Added examples/ruby/spec/drivers/remote_webdriver_spec.rb to files
    list for version updates
  • Replaced sed with perl for more reliable cross-platform version
    replacement
  • Implemented separate CDP version replacement using find and perl
    across all example source files
+31/-10 

@netlify
Copy link

netlify bot commented Oct 27, 2025

Deploy Preview for selenium-dev ready!

Name Link
🔨 Latest commit 0028a04
🔍 Latest deploy log https://app.netlify.com/projects/selenium-dev/deploys/6902383b3f9f34000806541e
😎 Deploy Preview https://deploy-preview-2514--selenium-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@qodo-merge-pro
Copy link
Contributor

qodo-merge-pro bot commented Oct 27, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Overbroad replacement

Description: Unvalidated direct substitution of version strings in files using perl -i -pe
"s/${OLD_VERSION}/${NEW_VERSION}/g" can unintentionally replace unrelated occurrences of
those numbers (e.g., part of URLs or other version fields), leading to supply-chain or
build integrity risks; consider anchoring patterns to specific dependency lines.
update-versions.sh [33-39]

Referred Code
for FILE_PATH in "${FILES[@]}"; do
    echo $FILE_PATH
    if [[ ! -f ${FILE_PATH} ]]; then
        echo "can't find file for replacement!"
    fi
    perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
done
Overbroad replacement

Description: Broad recursive find with perl in-place replacement for "v${OLD_CDP_VERSION}" across
multiple languages may corrupt unrelated strings (e.g., comments or other versioned
identifiers); scoping or stricter regex anchors recommended.
update-versions.sh [43-45]

Referred Code
find ./examples -type f \
    '(' -name "*.cs" -o -name "*.java" -o -name "*.js" -o -name "*.py" -o -name "*.rb" ')' \
    -exec perl -i -pe "s/v${OLD_CDP_VERSION}/v${NEW_CDP_VERSION}/g" {} \;
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
No auditing: The script performs file modifications and dependency installs without emitting structured
audit logs of actions, inputs, or outcomes beyond simple echoes.

Referred Code
# replace Selenium version
for FILE_PATH in "${FILES[@]}"; do
    echo $FILE_PATH
    if [[ ! -f ${FILE_PATH} ]]; then
        echo "can't find file for replacement!"
    fi
    perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
done


# replace CDP version
find ./examples -type f \
    '(' -name "*.cs" -o -name "*.java" -o -name "*.js" -o -name "*.py" -o -name "*.rb" ')' \
    -exec perl -i -pe "s/v${OLD_CDP_VERSION}/v${NEW_CDP_VERSION}/g" {} \;

pushd examples/ruby
bundle install
popd

pushd examples/javascript
npm install


 ... (clipped 1 lines)
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Weak validation: Argument checks and file existence handling echo messages but do not exit on missing files
or handle perl/find failures, risking silent partial updates.

Referred Code
for FILE_PATH in "${FILES[@]}"; do
    echo $FILE_PATH
    if [[ ! -f ${FILE_PATH} ]]; then
        echo "can't find file for replacement!"
    fi
    perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
done


# replace CDP version
find ./examples -type f \
    '(' -name "*.cs" -o -name "*.java" -o -name "*.js" -o -name "*.py" -o -name "*.rb" ')' \
    -exec perl -i -pe "s/v${OLD_CDP_VERSION}/v${NEW_CDP_VERSION}/g" {} \;
Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Unstructured logs: The script outputs unstructured echo statements and may print file paths and version
values without structured formatting, limiting auditability.

Referred Code
for FILE_PATH in "${FILES[@]}"; do
    echo $FILE_PATH
    if [[ ! -f ${FILE_PATH} ]]; then
        echo "can't find file for replacement!"
    fi
    perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
done


# replace CDP version
find ./examples -type f \
    '(' -name "*.cs" -o -name "*.java" -o -name "*.js" -o -name "*.py" -o -name "*.rb" ')' \
    -exec perl -i -pe "s/v${OLD_CDP_VERSION}/v${NEW_CDP_VERSION}/g" {} \;
Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unsafe regex: User-supplied version strings are interpolated directly into perl regex replacements
without escaping, which could misbehave for special characters.

Referred Code
    perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
done


# replace CDP version
find ./examples -type f \
    '(' -name "*.cs" -o -name "*.java" -o -name "*.js" -o -name "*.py" -o -name "*.rb" ')' \
    -exec perl -i -pe "s/v${OLD_CDP_VERSION}/v${NEW_CDP_VERSION}/g" {} \;
  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-merge-pro
Copy link
Contributor

qodo-merge-pro bot commented Oct 27, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Escape regex metacharacters in version

Escape regex metacharacters in the OLD_VERSION variable within the perl command
to ensure the version string is treated as a literal.

scripts/update-versions.sh [38]

-perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
+perl -i -pe "s/\Q${OLD_VERSION}\E/${NEW_VERSION}/g" "${FILE_PATH}"
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a latent bug where dots in the version string are treated as regex wildcards, preventing incorrect replacements and improving the script's reliability.

Medium
Use a non-zero exit code
Suggestion Impact:The commit changed the exit on invalid version format from a plain exit to exit 1, implementing the non-zero exit code as suggested.

code diff:

 if [[ "$1" != *.*.* || "$2" != *.*.* ]] ; then
-    echo "fatal: use major.minor.minor version numbers (e.g.: 4.38.0)"
-    exit
+    echo "fatal: use major.minor.patch version numbers (e.g.: 4.38.0)"
+    exit 1
 fi

Modify the script to exit with a non-zero status code when the version number
format is invalid, ensuring that errors are properly signaled.

scripts/update-versions.sh [11-14]

 if [[ "$1" != *.*.* || "$2" != *.*.* ]] ; then
     echo "fatal: use major.minor.minor version numbers (e.g.: 4.38.0)"
-    exit
+    exit 1
 fi

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a bug where the script exits with a success code (0) upon validation failure, which should be an error state.

Medium
High-level
Use more robust version replacement

The current version replacement uses a global search-and-replace, which is
fragile. It should be updated to use more specific regular expressions, like
word boundaries, to prevent accidental replacement of substrings.

Examples:

scripts/update-versions.sh [38]
    perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
scripts/update-versions.sh [45]
    -exec perl -i -pe "s/v${OLD_CDP_VERSION}/v${NEW_CDP_VERSION}/g" {} \;

Solution Walkthrough:

Before:

OLD_VERSION="$1"
NEW_VERSION="$2"
OLD_CDP_VERSION="$3"
NEW_CDP_VERSION="$4"

# ...
for FILE_PATH in "${FILES[@]}"; do
    perl -i -pe "s/${OLD_VERSION}/${NEW_VERSION}/g" "${FILE_PATH}"
done

find ./examples -type f ... \
    -exec perl -i -pe "s/v${OLD_CDP_VERSION}/v${NEW_CDP_VERSION}/g" {} \;

After:

OLD_VERSION="$1"
NEW_VERSION="$2"
OLD_CDP_VERSION="$3"
NEW_CDP_VERSION="$4"

# ...
for FILE_PATH in "${FILES[@]}"; do
    # Use word boundaries to avoid partial matches
    perl -i -pe "s/\b${OLD_VERSION}\b/${NEW_VERSION}/g" "${FILE_PATH}"
done

find ./examples -type f ... \
    -exec perl -i -pe "s/v\b${OLD_CDP_VERSION}\b/v${NEW_CDP_VERSION}/g" {} \;
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that the global string replacement for versions is fragile and could lead to incorrect substitutions, proposing a more robust regex-based approach which is a significant improvement to the script's core logic.

Medium
  • Update

@diemol diemol merged commit 1295900 into SeleniumHQ:trunk Oct 29, 2025
4 checks passed
@cgoldberg cgoldberg deleted the update-version-script branch October 29, 2025 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants