Skip to content

Conversation

@titusfortner
Copy link
Member

@titusfortner titusfortner commented Jan 20, 2026

User description

We are checking out more than we need to. A full fetch takes over a minute
We specify fetch depth a bunch of places we don't need to.

💥 What does this PR do?

Optimizes fetch-depth across workflows to avoid fetching full git history when not needed:

  1. bazel.yml: Auto-detects optimal fetch-depth based on event type (PR commits + 1, push commits + 1, or default 1)
  2. pre-release.yml: Calculates tag-based depth for changelog generation using GitHub API
  3. Removes unnecessary fetch-depth overrides from ci.yml, ci-grid-ui.yml, mirror-selenium-releases.yml, and pre-release.yml

🔧 Implementation Notes

My first thought was to create a custom action for this. Turns out you can't have a custom action for checking out because you have to... check it out first.

Two distinct fetch-depth calculation strategies:

  • Event-based (bazel.yml): Uses PR/push commit count from GitHub event context
  • Tag-based (pre-release.yml): Counts commits since previous release tag via gh api

🔄 Types of changes

  • Cleanup (formatting, renaming)

PR Type

Enhancement


Description

  • Adds intelligent fetch-depth calculation for changelog generation

  • Uses GitHub API to count commits since previous release tag

  • Calculates optimal depth based on version pattern matching

  • Handles edge cases for first releases and missing tags gracefully


Diagram Walkthrough

flowchart LR
  normalize["normalize-version"] -->|version| calc["calculate-changelog-depth"]
  calc -->|depth output| changelog["generate-changelogs"]
  changelog -->|uses fetch-depth| checkout["git checkout"]
Loading

File Walkthrough

Relevant files
Enhancement
pre-release.yml
Add tag-based fetch-depth calculation job                               

.github/workflows/pre-release.yml

  • Introduces new calculate-changelog-depth job that determines optimal
    git fetch depth
  • Parses semantic version to identify previous release tag
  • Uses GitHub API to count commits between tags for accurate depth
    calculation
  • Adds fallback to full history (depth=0) for first releases and API
    failures
  • Updates generate-changelogs job to depend on and use calculated depth
+43/-1   

@titusfortner titusfortner requested a review from Copilot January 20, 2026 22:02
@selenium-ci selenium-ci added the B-build Includes scripting, bazel and CI integrations label Jan 20, 2026
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 20, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
GitHub output injection

Description: Potential GitHub Actions output-injection: the workflow writes ${{ inputs.fetch-depth }}
directly into $GITHUB_OUTPUT via echo "val=$FETCH_DEPTH" >> "$GITHUB_OUTPUT", so if a
caller can supply a value containing newlines (e.g., 1\nother=malicious), it could spoof
additional step outputs and influence later workflow behavior.
bazel.yml [88-107]

Referred Code
- name: Calculate fetch depth
  id: depth
  env:
    FETCH_DEPTH: ${{ inputs.fetch-depth }}
    PR_COMMITS: ${{ github.event.pull_request.commits }}
  run: |
    if [ -n "$FETCH_DEPTH" ]; then
      echo "val=$FETCH_DEPTH" >> "$GITHUB_OUTPUT"
    elif [ -n "$PR_COMMITS" ]; then
      echo "val=$((PR_COMMITS + 1))" >> "$GITHUB_OUTPUT"
    else
      COMMIT_COUNT=$(jq -e '.commits | length // 0' "$GITHUB_EVENT_PATH" 2>/dev/null) || COMMIT_COUNT=0
      echo "val=$((COMMIT_COUNT + 1))" >> "$GITHUB_OUTPUT"
    fi
- name: Checkout source tree
  uses: actions/checkout@v4
  with:
    ref: ${{ inputs.ref || github.ref }}
    fetch-depth: ${{ steps.depth.outputs.val }}
- name: Pull latest changes from head ref for PRs
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: Comprehensive Audit Trails

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

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

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

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

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

Learn more about managing compliance generic rules or creating your own custom rules

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: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

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

Status:
Errors silently suppressed: The new gh api compare call suppresses errors (2>/dev/null || echo "0") and
may silently proceed with an incorrect fetch-depth when tags are missing or the API call
fails, reducing debuggability and masking edge cases.

Referred Code
  COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...HEAD" --jq '.total_commits' 2>/dev/null || echo "0")
  echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
else
  echo "depth=0" >> "$GITHUB_OUTPUT"

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

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

Status:
Unvalidated fetch-depth: The new workflow accepts inputs.fetch-depth as an unvalidated string and forwards it to
actions/checkout, so non-numeric values could cause workflow failures or unexpected
behavior.

Referred Code
- name: Calculate fetch depth
  id: depth
  env:
    FETCH_DEPTH: ${{ inputs.fetch-depth }}
    PR_COMMITS: ${{ github.event.pull_request.commits }}
  run: |
    if [ -n "$FETCH_DEPTH" ]; then
      echo "val=$FETCH_DEPTH" >> "$GITHUB_OUTPUT"
    elif [ -n "$PR_COMMITS" ]; then
      echo "val=$((PR_COMMITS + 1))" >> "$GITHUB_OUTPUT"
    else
      COMMIT_COUNT=$(jq -e '.commits | length // 0' "$GITHUB_EVENT_PATH" 2>/dev/null) || COMMIT_COUNT=0
      echo "val=$((COMMIT_COUNT + 1))" >> "$GITHUB_OUTPUT"
    fi
- name: Checkout source tree
  uses: actions/checkout@v4
  with:
    ref: ${{ inputs.ref || github.ref }}
    fetch-depth: ${{ steps.depth.outputs.val }}
- name: Pull latest changes from head ref for PRs

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 20, 2026

PR Code Suggestions ✨

Latest suggestions up to 30d515d

CategorySuggestion                                                                                                                                    Impact
Possible issue
Make auto-depth event-aware

Improve the auto-detection of fetch depth by making it event-aware. Explicitly
handle pull_request and push events, and default to a full history (0) for all
other event types to prevent issues with shallow clones.

.github/workflows/bazel.yml [93-109]

 - name: Calculate fetch depth
   id: depth
   env:
     FETCH_DEPTH: ${{ inputs.fetch-depth }}
     PR_COMMITS: ${{ github.event.pull_request.commits }}
+    EVENT_NAME: ${{ github.event_name }}
   run: |
     # Use explicit value if provided
     if [ -n "$FETCH_DEPTH" ]; then
       echo "val=$FETCH_DEPTH" >> "$GITHUB_OUTPUT"
     # For PRs, use commit count plus buffer for merge base
-    elif [ -n "$PR_COMMITS" ]; then
+    elif [ "$EVENT_NAME" = "pull_request" ] || [ "$EVENT_NAME" = "pull_request_target" ]; then
       echo "val=$((PR_COMMITS + 2))" >> "$GITHUB_OUTPUT"
     # For push events, read commit count from event payload
+    elif [ "$EVENT_NAME" = "push" ]; then
+      COMMIT_COUNT=$(jq -r '(.commits // []) | length' "$GITHUB_EVENT_PATH" 2>/dev/null) || COMMIT_COUNT=0
+      echo "val=$((COMMIT_COUNT + 1))" >> "$GITHUB_OUTPUT"
+    # For other events, default to full history to avoid shallow-clone failures
     else
-      COMMIT_COUNT=$(jq -e '.commits | length // 0' "$GITHUB_EVENT_PATH" 2>/dev/null) || COMMIT_COUNT=0
-      echo "val=$((COMMIT_COUNT + 1))" >> "$GITHUB_OUTPUT"
+      echo "val=0" >> "$GITHUB_OUTPUT"
     fi
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a logic flaw in the new fetch-depth calculation where non-PR/push events would incorrectly default to a shallow clone of depth 1, which could break workflows; proposing a safer default to full history (0) significantly improves robustness.

Medium
Fetch base branch ref reliably

Fetch the pull request's base branch by its ref
(github.event.pull_request.base.ref) instead of its SHA
(github.event.pull_request.base.sha) to ensure the git fetch command is
reliable.

.github/workflows/bazel.yml [115-117]

 - name: Fetch base ref for PR comparison
-  if: github.event.pull_request.base.sha
-  run: git fetch --depth=1 origin ${{ github.event.pull_request.base.sha }}
+  if: github.event.pull_request.base.ref
+  run: git fetch --depth=1 origin ${{ github.event.pull_request.base.ref }}
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly points out that fetching by SHA can be unreliable and proposes a more robust method of fetching by branch ref, which prevents potential intermittent CI failures.

Medium
Incremental [*]
Fetch base SHA into ref

Improve the robustness of the git fetch command by fetching the pull request's
base SHA into a stable named reference instead of relying on the transient
FETCH_HEAD.

.github/workflows/bazel.yml [115-117]

 - name: Fetch base ref for PR comparison
   if: github.event.pull_request.base.sha
-  run: git fetch --depth=1 origin ${{ github.event.pull_request.base.sha }}
+  run: |
+    git fetch --no-tags --update-shallow --depth=1 origin \
+      "${{ github.event.pull_request.base.sha }}:refs/remotes/origin/pr-base"
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that fetching a SHA only updates FETCH_HEAD, and proposes a more robust solution by fetching it into a stable named reference, which improves the reliability of subsequent git operations.

Medium
  • Update

Previous suggestions

Suggestions up to commit eb62caf
CategorySuggestion                                                                                                                                    Impact
Possible issue
Validate commit count before arithmetic

Add a check to ensure the COUNT variable is a non-negative integer before
performing arithmetic. If the check fails, fall back to a full fetch (depth=0)
to prevent the job from failing.

.github/workflows/pre-release.yml [171-176]

 COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...${{ github.sha }}" --jq '.total_commits' 2>/dev/null) || {
   echo "::warning::Failed to get commit count, using full history"
   echo "depth=0" >> "$GITHUB_OUTPUT"
   exit 0
 }
+
+if ! [[ "${COUNT:-}" =~ ^[0-9]+$ ]]; then
+  echo "::warning::Unexpected commit count '${COUNT}', using full history"
+  echo "depth=0" >> "$GITHUB_OUTPUT"
+  exit 0
+fi
+
 echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
Suggestion importance[1-10]: 7

__

Why: This suggestion adds a defensive check to validate that the commit count from the GitHub API is a number before using it in an arithmetic operation, preventing a potential workflow failure.

Medium
Add merge-base buffer for pushes

Increase the fetch depth for push events by changing COMMIT_COUNT + 1 to
COMMIT_COUNT + 2 to provide a larger buffer for git operations, similar to how
pull requests are handled.

.github/workflows/bazel.yml [107-108]

 COMMIT_COUNT=$(jq -e '.commits | length // 0' "$GITHUB_EVENT_PATH" 2>/dev/null) || COMMIT_COUNT=0
-echo "val=$((COMMIT_COUNT + 1))" >> "$GITHUB_OUTPUT"
+echo "val=$((COMMIT_COUNT + 2))" >> "$GITHUB_OUTPUT"
Suggestion importance[1-10]: 4

__

Why: The suggestion improves robustness by increasing the fetch depth buffer for push events, aligning it with the logic for pull requests and potentially preventing issues with git history in some edge cases.

Low
Suggestions up to commit 0053fec
CategorySuggestion                                                                                                                                    Impact
Incremental [*]
Make auto-detection always numeric

Add validation to the Calculate fetch depth step to ensure the fetch-depth value
is always a valid integer, preventing potential workflow failures.

.github/workflows/bazel.yml [99-109]

-# Use explicit value if provided
-if [ -n "$FETCH_DEPTH" ]; then
-  echo "val=$FETCH_DEPTH" >> "$GITHUB_OUTPUT"
-# For PRs, use commit count plus buffer for merge base
-elif [ -n "$PR_COMMITS" ]; then
-  echo "val=$((PR_COMMITS + 2))" >> "$GITHUB_OUTPUT"
-# For push events, read commit count from event payload
+set -euo pipefail
+
+# Normalize explicit value (treat whitespace as empty) and validate it's numeric
+FETCH_DEPTH_TRIMMED="$(printf '%s' "${FETCH_DEPTH:-}" | tr -d '[:space:]')"
+if [ -n "$FETCH_DEPTH_TRIMMED" ]; then
+  if ! [[ "$FETCH_DEPTH_TRIMMED" =~ ^[0-9]+$ ]]; then
+    echo "::error::inputs.fetch-depth must be a non-negative integer (or empty for auto-detect)"
+    exit 1
+  fi
+  echo "val=$FETCH_DEPTH_TRIMMED" >> "$GITHUB_OUTPUT"
+  exit 0
+fi
+
+# Auto-detect depth from the event payload
+if jq -e '.pull_request.commits' "$GITHUB_EVENT_PATH" >/dev/null 2>&1; then
+  PR_COUNT="$(jq -r '.pull_request.commits // 0' "$GITHUB_EVENT_PATH" 2>/dev/null || echo 0)"
+  echo "val=$((PR_COUNT + 2))" >> "$GITHUB_OUTPUT"
 else
-  COMMIT_COUNT=$(jq -e '.commits | length // 0' "$GITHUB_EVENT_PATH" 2>/dev/null) || COMMIT_COUNT=0
+  COMMIT_COUNT="$(jq -r '(.commits | length) // 0' "$GITHUB_EVENT_PATH" 2>/dev/null || echo 0)"
   echo "val=$((COMMIT_COUNT + 1))" >> "$GITHUB_OUTPUT"
 fi
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies and fixes multiple edge cases where the script could fail or produce an invalid fetch-depth, making the workflow significantly more robust.

Medium
Add safe checkout fallback

Add a fallback value for fetch-depth in the checkout step to handle cases where
the calculation step fails to produce an output.

.github/workflows/bazel.yml [114]

-fetch-depth: ${{ steps.depth.outputs.val }}
+fetch-depth: ${{ steps.depth.outputs.val || '1' }}
Suggestion importance[1-10]: 5

__

Why: The suggestion correctly identifies a potential failure mode where the Calculate fetch depth step might not produce an output, and provides a reasonable fallback to prevent the checkout step from failing.

Low
Prevent invalid depth values

Update the description for the fetch-depth input to clarify that it must be a
non-negative integer to prevent potential workflow failures.

.github/workflows/bazel.yml [69-73]

 fetch-depth:
-        description: Number of commits to fetch (0 for full history, empty for auto-detect)
+        description: Number of commits to fetch (0 for full history; leave empty to auto-detect). Must be a non-negative integer.
         required: false
         type: string
         default: ''
Suggestion importance[1-10]: 3

__

Why: The suggestion correctly identifies that changing the fetch-depth input type to string can cause issues, but the proposed fix only updates the description, which is a minor improvement.

Low
Possible issue
Make depth calculation cross-platform

To ensure cross-platform compatibility, specify shell: bash for the 'Calculate
fetch depth' step and replace the jq command with a Python script.

.github/workflows/bazel.yml [93-109]

 - name: Calculate fetch depth
   id: depth
+  shell: bash
   env:
     FETCH_DEPTH: ${{ inputs.fetch-depth }}
     PR_COMMITS: ${{ github.event.pull_request.commits }}
   run: |
     # Use explicit value if provided
     if [ -n "$FETCH_DEPTH" ]; then
       echo "val=$FETCH_DEPTH" >> "$GITHUB_OUTPUT"
     # For PRs, use commit count plus buffer for merge base
     elif [ -n "$PR_COMMITS" ]; then
       echo "val=$((PR_COMMITS + 2))" >> "$GITHUB_OUTPUT"
     # For push events, read commit count from event payload
     else
-      COMMIT_COUNT=$(jq -e '.commits | length // 0' "$GITHUB_EVENT_PATH" 2>/dev/null) || COMMIT_COUNT=0
+      COMMIT_COUNT="$(
+        python - <<'PY'
+        import json, os
+        path = os.environ.get("GITHUB_EVENT_PATH", "")
+        try:
+          with open(path, "r", encoding="utf-8") as f:
+            data = json.load(f)
+          commits = data.get("commits") or []
+          print(len(commits))
+        except Exception:
+          print(0)
+        PY
+      )"
       echo "val=$((COMMIT_COUNT + 1))" >> "$GITHUB_OUTPUT"
     fi
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a cross-platform compatibility issue that would cause the workflow to fail on Windows runners and provides a robust solution by specifying shell: bash and replacing a non-standard dependency (jq) with a portable Python script.

Medium
Suggestions up to commit b8e1b39
CategorySuggestion                                                                                                                                    Impact
Possible issue
Use correct previous release tag

When calculating the previous version for a new minor release, find the latest
tag of the previous minor version instead of assuming the .0 patch release.

.github/workflows/pre-release.yml [156-166]

 if [ "$PATCH" -gt 1 ]; then
   PREV="selenium-${MAJOR}.${MINOR}.$((PATCH-1))"
 elif [ "$PATCH" -eq 1 ]; then
   PREV="selenium-${MAJOR}.${MINOR}.0"
 elif [ "$MINOR" -gt 0 ]; then
-  PREV="selenium-${MAJOR}.$((MINOR-1)).0"
+  PREV_MINOR="$((MINOR-1))"
+  PREV=$(
+    gh api "repos/${{ github.repository }}/tags?per_page=100" --jq \
+      --arg prefix "selenium-${MAJOR}.${PREV_MINOR}." '
+        [.[].name | select(startswith($prefix))] | sort | last
+      ' 2>/dev/null
+  )
+  if [ -z "${PREV:-}" ] || [ "$PREV" = "null" ]; then
+    echo "::warning::No previous minor tag found; using full history"
+    echo "depth=0" >> "$GITHUB_OUTPUT"
+    exit 0
+  fi
 else
   # First release of major version (X.0.0), use full history
   echo "depth=0" >> "$GITHUB_OUTPUT"
   exit 0
 fi
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a significant logic flaw where calculating the previous tag for a new minor release (e.g., 4.13.0) incorrectly uses .0 of the previous minor (e.g., 4.12.0) instead of the latest patch release, which would lead to an incomplete changelog.

High
Validate numeric commit count

Add a check to validate that the COUNT variable is a numeric value before using
it in an arithmetic operation to prevent the script from failing.

.github/workflows/pre-release.yml [168-173]

 COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...${{ github.sha }}" --jq '.total_commits' 2>/dev/null) || {
   echo "::warning::Failed to get commit count, using full history"
   echo "depth=0" >> "$GITHUB_OUTPUT"
   exit 0
 }
+
+if ! [[ "${COUNT:-}" =~ ^[0-9]+$ ]]; then
+  echo "::warning::Unexpected commit count '${COUNT}', using full history"
+  echo "depth=0" >> "$GITHUB_OUTPUT"
+  exit 0
+fi
+
 echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that the COUNT variable might not be a number, which would cause the script to fail. Adding a check to ensure COUNT is numeric before performing arithmetic improves the robustness of the script.

Medium
Suggestions up to commit 4e3665a
CategorySuggestion                                                                                                                                    Impact
Possible issue
Add fallback on API failure

Add error handling for the gh api call in bazel.yml. If the call fails, fall
back to a full history fetch (fetch-depth: 0) to prevent workflow failure.

.github/workflows/bazel.yml [123-124]

-COUNT=$(gh api "repos/${{ github.repository }}/compare/${BASE}...${AFTER_SHA}" --jq '.total_commits')
-echo "val=$((COUNT + 2))" >> "$GITHUB_OUTPUT"
+if COUNT=$(gh api "repos/${{ github.repository }}/compare/${BASE}...${AFTER_SHA}" --jq '.total_commits' 2>/dev/null); then
+  echo "val=$((COUNT + 2))" >> "$GITHUB_OUTPUT"
+else
+  echo "::warning::Failed to compute commit range depth; falling back to full history"
+  echo "val=0" >> "$GITHUB_OUTPUT"
+fi
Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a potential runtime error if the gh api call fails and provides a robust solution, preventing the workflow from failing. The author implemented similar logic in another file, making this a valuable catch for consistency and reliability.

Medium
General
Provide default branch to script

Pass the repository's default branch to the script's environment via
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}. This allows the
script to dynamically use the correct default branch name.

.github/workflows/bazel.yml [106-111]

 env:
   GH_TOKEN: ${{ github.token }}
   FETCH_DEPTH: ${{ inputs.fetch-depth }}
   PR_COMMITS: ${{ github.event.pull_request.commits }}
   BEFORE_SHA: ${{ github.event.before }}
   AFTER_SHA: ${{ github.event.after }}
+  DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly proposes to pass the repository's default branch as an environment variable, which makes the script more robust by avoiding a hard-coded branch name like trunk.

Medium
Learned
best practice
Centralize duplicated workflow logic

Extract this tag-to-depth calculation into a shared script/composite action so
fetch-depth logic isn’t reimplemented across workflows.

.github/workflows/pre-release.yml [161-193]

 - name: Calculate fetch depth from tag
   id: calc
   env:
     GH_TOKEN: ${{ github.token }}
     VERSION: ${{ needs.normalize-version.outputs.version }}
   run: |
-    set -euo pipefail
-    if [[ "$VERSION" =~ ([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
-      MAJOR=${BASH_REMATCH[1]}
-      MINOR=${BASH_REMATCH[2]}
-      PATCH=${BASH_REMATCH[3]}
+    ./.github/scripts/calculate-fetch-depth-from-version.sh "$VERSION" "${{ github.repository }}" "${{ github.sha }}" >> "$GITHUB_OUTPUT"
 
-      if [ "$PATCH" -gt 1 ]; then
-        PREV="selenium-${MAJOR}.${MINOR}.$((PATCH-1))"
-      elif [ "$PATCH" -eq 1 ]; then
-        PREV="selenium-${MAJOR}.${MINOR}.0"
-      elif [ "$MINOR" -gt 0 ]; then
-        PREV="selenium-${MAJOR}.$((MINOR-1)).0"
-      else
-        # First release of major version (X.0.0), use full history
-        echo "depth=0" >> "$GITHUB_OUTPUT"
-        exit 0
-      fi
-
-      COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...${{ github.sha }}" --jq '.total_commits' 2>/dev/null) || {
-        echo "::warning::Failed to get commit count, using full history"
-        echo "depth=0" >> "$GITHUB_OUTPUT"
-        exit 0
-      }
-      echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
-    else
-      echo "depth=0" >> "$GITHUB_OUTPUT"
-    fi
-
Suggestion importance[1-10]: 5

__

Why:
Relevant best practice - Reduce duplication by centralizing shared workflow logic (single source for repeated behavior).

Low
Suggestions up to commit 6eba0f4
CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix incorrect previous tag calculation

Fix a bug in the previous version calculation by using gh release list to
robustly find the previous release tag, which avoids incorrect version
decrementing on major/minor version boundaries.

.github/workflows/pre-release.yml [167-184]

 if [[ "$VERSION" =~ ([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
-  MAJOR=${BASH_REMATCH[1]}
-  MINOR=${BASH_REMATCH[2]}
-  PATCH=${BASH_REMATCH[3]}
+  # Get the previous release tag to calculate the number of commits
+  PREV=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null)
 
-  if [ "$PATCH" -gt 1 ]; then
-    PREV="selenium-${MAJOR}.${MINOR}.$((PATCH-1))"
-  elif [ "$PATCH" -eq 1 ]; then
-    PREV="selenium-${MAJOR}.${MINOR}.0"
+  if [ -n "$PREV" ]; then
+    COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...HEAD" --jq '.total_commits' 2>/dev/null || echo "0")
+    echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
   else
-    PREV="selenium-${MAJOR}.$((MINOR-1)).0"
+    # Fallback if no previous release is found
+    echo "depth=0" >> "$GITHUB_OUTPUT"
   fi
-
-  COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...HEAD" --jq '.total_commits' 2>/dev/null || echo "0")
-  echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
 else
   echo "depth=0" >> "$GITHUB_OUTPUT"
 fi
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical bug in the new version calculation logic that would fail for major/minor releases and proposes a more robust solution using gh release list.

High
Validate fetch-depth input

Add a numeric check to validate the FETCH_DEPTH input, ensuring only valid
numbers are passed to the checkout step.

.github/workflows/bazel.yml [94-95]

-if [ -n "$FETCH_DEPTH" ]; then
+if [[ "$FETCH_DEPTH" =~ ^[0-9]+$ ]]; then
   echo "val=$FETCH_DEPTH" >> "$GITHUB_OUTPUT"
Suggestion importance[1-10]: 5

__

Why: The suggestion improves the robustness of the script by validating that FETCH_DEPTH is a number, preventing potential errors if a non-numeric string is passed.

Low
General
Fallback to full history on error

Improve error handling for the gh api call by falling back to a full history
(depth=0) on failure, ensuring the changelog generation is complete.

.github/workflows/pre-release.yml [180-181]

-COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...HEAD" --jq '.total_commits' 2>/dev/null || echo "0")
-echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
+if COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...HEAD" --jq '.total_commits' 2>/dev/null); then
+  echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
+else
+  echo "depth=0" >> "$GITHUB_OUTPUT"
+fi
Suggestion importance[1-10]: 7

__

Why: The suggestion improves error handling by correctly capturing failures from the gh api call and falling back to a safe default (depth=0), which is more appropriate for this workflow than the current behavior.

Medium
Enable strict shell mode

Add set -euo pipefail to the beginning of the shell script to enable strict
error checking and prevent silent failures.

.github/workflows/bazel.yml [94]

+set -euo pipefail
 if [ -n "$FETCH_DEPTH" ]; then
Suggestion importance[1-10]: 4

__

Why: This is a good practice for shell scripts to prevent silent failures, but it is not applied consistently across other scripts in the PR, making its impact moderate.

Low

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to optimize fetch-depth across GitHub Actions workflows to reduce checkout times by avoiding unnecessary full git history fetches. However, the implementation contains critical breaking changes that will cause workflow failures.

Changes:

  • Introduces auto-detection of optimal fetch-depth in bazel.yml based on event type (PR commits, push commits, or default)
  • Adds tag-based depth calculation for changelog generation in pre-release.yml
  • Removes explicit fetch-depth overrides from ci.yml, ci-grid-ui.yml, mirror-selenium-releases.yml, and pre-release.yml
  • Removes input parameters and setup steps for dotnet-version, java-version, and browser-version from bazel.yml

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
.github/workflows/bazel.yml Adds auto-detect fetch-depth logic; removes dotnet-version, java-version, browser-version inputs and their corresponding setup steps; changes fetch-depth type from number to string
.github/workflows/pre-release.yml Adds calculate-changelog-depth job to compute tag-based fetch depth; removes fetch-depth: 0 from two checkout steps; adds fetch-depth parameter to generate-changelogs job
.github/workflows/ci.yml Removes fetch-depth: 50 from check-targets job (now uses auto-detect)
.github/workflows/ci-grid-ui.yml Removes fetch-depth: 50 from checkout step (now uses default shallow)
.github/workflows/mirror-selenium-releases.yml Removes fetch-depth: 0 from checkout step (now uses default shallow)

@titusfortner titusfortner force-pushed the optimize-fetch-depth branch 2 times, most recently from 1f3c790 to a5e6981 Compare January 20, 2026 22:32
@titusfortner titusfortner marked this pull request as draft January 22, 2026 04:47
@titusfortner titusfortner marked this pull request as ready for review January 24, 2026 07:28
@titusfortner titusfortner requested a review from Copilot January 24, 2026 07:28
@qodo-code-review
Copy link
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
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: Comprehensive Audit Trails

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

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

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

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

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

Learn more about managing compliance generic rules or creating your own custom rules

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: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

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

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Robust Error Handling and Edge Case Management

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

Status:
Unvalidated API output: The workflow assumes gh api returns a numeric .total_commits and performs arithmetic on
COUNT without validation, which can fail under set -euo pipefail and stop the workflow
without a graceful fallback.

Referred Code
COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...${{ github.sha }}" --jq '.total_commits' 2>/dev/null) || {
  echo "::warning::Failed to get commit count, using full history"
  echo "depth=0" >> "$GITHUB_OUTPUT"
  exit 0
}
echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

Persistent suggestions updated to latest commit b8e1b39

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 24, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Improve previous tag calculation logic

To improve robustness, modify the previous tag calculation to use a full fetch
(depth=0) for new minor releases, as the current logic for guessing the previous
tag is flawed and may fail.

.github/workflows/pre-release.yml [156-166]

-if [ "$PATCH" -gt 1 ]; then
+if [ "$PATCH" -gt 0 ]; then
   PREV="selenium-${MAJOR}.${MINOR}.$((PATCH-1))"
-elif [ "$PATCH" -eq 1 ]; then
-  PREV="selenium-${MAJOR}.${MINOR}.0"
 elif [ "$MINOR" -gt 0 ]; then
-  PREV="selenium-${MAJOR}.$((MINOR-1)).0"
+  # New minor release (X.Y.0), use full history as previous tag is uncertain
+  echo "::warning::New minor release, using full history to be safe."
+  echo "depth=0" >> "$GITHUB_OUTPUT"
+  exit 0
 else
   # First release of major version (X.0.0), use full history
   echo "depth=0" >> "$GITHUB_OUTPUT"
   exit 0
 fi
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a logical flaw in guessing the previous tag for new minor releases and proposes a more robust, safer fallback, which prevents potential errors in the changelog generation.

Medium
Learned
best practice
Validate external inputs and API output

Guard against blank/whitespace VERSION and non-numeric/empty COUNT from the
GitHub API before doing arithmetic, otherwise the step can fail despite the
fallback intent.

.github/workflows/pre-release.yml [149-176]

 run: |
   set -euo pipefail
-  if [[ "$VERSION" =~ ([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
+
+  VERSION="$(printf '%s' "${VERSION:-}" | xargs)"
+  if [[ "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
     MAJOR=${BASH_REMATCH[1]}
     MINOR=${BASH_REMATCH[2]}
     PATCH=${BASH_REMATCH[3]}
 
     if [ "$PATCH" -gt 1 ]; then
       PREV="selenium-${MAJOR}.${MINOR}.$((PATCH-1))"
     elif [ "$PATCH" -eq 1 ]; then
       PREV="selenium-${MAJOR}.${MINOR}.0"
     elif [ "$MINOR" -gt 0 ]; then
       PREV="selenium-${MAJOR}.$((MINOR-1)).0"
     else
-      # First release of major version (X.0.0), use full history
       echo "depth=0" >> "$GITHUB_OUTPUT"
       exit 0
     fi
 
-    COUNT=$(gh api "repos/${{ github.repository }}/compare/${PREV}...${{ github.sha }}" --jq '.total_commits' 2>/dev/null) || {
-      echo "::warning::Failed to get commit count, using full history"
+    COUNT="$(gh api "repos/${{ github.repository }}/compare/${PREV}...${{ github.sha }}" --jq '.total_commits' 2>/dev/null || true)"
+    if [[ -z "$COUNT" || ! "$COUNT" =~ ^[0-9]+$ ]]; then
+      echo "::warning::Failed to get numeric commit count, using full history"
       echo "depth=0" >> "$GITHUB_OUTPUT"
       exit 0
-    }
+    fi
+
     echo "depth=$((COUNT + 10))" >> "$GITHUB_OUTPUT"
   else
     echo "depth=0" >> "$GITHUB_OUTPUT"
   fi
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Add explicit validation/guards at integration boundaries (GitHub Actions inputs/API outputs) by trimming inputs and checking presence/type before use.

Low
  • More

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

@titusfortner titusfortner merged commit 4910110 into trunk Jan 24, 2026
24 checks passed
@titusfortner titusfortner deleted the optimize-fetch-depth branch January 24, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

B-build Includes scripting, bazel and CI integrations Review effort 2/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants