Skip to content

Conversation

@titusfortner
Copy link
Member

@titusfortner titusfortner commented Jan 19, 2026

User description

Nightly job ran mid-release yesterday and it was suboptimal. This will prevent that.
Plan in #16947 is to run nightly at the end of the release anyway since things expect a nightly tag.

💥 What does this PR do?

  • Prevent nightly releases while a release is in progress

🔧 Implementation Notes

Checks whether release ruleset is active before proceeding with nightly build.

🔄 Types of changes

  • Bug fix (backwards compatible)

PR Type

Bug fix


Description

  • Prevent nightly releases during active release windows

  • Add check-release job to detect active release ruleset

  • Update all language jobs to depend on release check

  • Skip nightly builds when release is in progress


Diagram Walkthrough

flowchart LR
  A["check-release job"] -- "outputs release-in-progress" --> B["ruby job"]
  A -- "outputs release-in-progress" --> C["python job"]
  A -- "outputs release-in-progress" --> D["java job"]
  A -- "outputs release-in-progress" --> E["dotnet job"]
  A -- "outputs release-in-progress" --> F["grid job"]
  A -- "outputs release-in-progress" --> G["javascript job"]
  B -- "skipped if releasing" --> H["nightly workflow"]
  C -- "skipped if releasing" --> H
  D -- "skipped if releasing" --> H
  E -- "skipped if releasing" --> H
  F -- "skipped if releasing" --> H
  G -- "skipped if releasing" --> H
Loading

File Walkthrough

Relevant files
Configuration changes
nightly.yml
Add release window detection to nightly workflow                 

.github/workflows/nightly.yml

  • Added new check-release job that queries GitHub API to detect if
    release ruleset is active
  • Updated all language-specific jobs (ruby, python, java, dotnet, grid,
    javascript) to depend on check-release
  • Modified conditional logic in all jobs to skip execution when
    release-in-progress output is true
  • Prevents nightly releases from running concurrently with active
    release processes
+27/-6   

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

qodo-code-review bot commented Jan 19, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Excessive token permissions

Description: The new check-release job inherits the workflow-wide permissions (including packages:
write) even though it only queries the GitHub API, so a compromise of this job/step could
unnecessarily allow package publishing or other write-scoped actions via
secrets.GITHUB_TOKEN (consider scoping permissions per-job to least privilege).
nightly.yml [31-50]

Referred Code
permissions:
  contents: read
  packages: write

jobs:
  check-release:
    name: Check Release Window
    runs-on: ubuntu-latest
    if: github.event.repository.fork == false
    outputs:
      release-in-progress: ${{ steps.check.outputs.releasing }}
    steps:
      - name: Check if release ruleset is active
        id: check
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
          echo "releasing=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
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:
Missing failure handling: The gh api call used to determine release-in-progress has no explicit fallback/handling
for API errors or ruleset-ID changes, which could cause the workflow to fail or
incorrectly block nightlies.

Referred Code
ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
echo "releasing=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"

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 19, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Avoid hardcoded ID for ruleset lookup
Suggestion Impact:The commit did not implement dynamic lookup by ruleset name and still uses the hardcoded ruleset ID (11911909). However, it added robustness by setting bash shell options and handling API failure with a warning and a fallback output, partially addressing the "make the workflow more robust" intent of the suggestion.

code diff:

+        shell: bash
         run: |
-          ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
-          echo "releasing=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
+          set -euo pipefail
+          # Ruleset 11911909 is "Release In Progress Access" - see restrict-trunk.yml
+          if ! ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement' 2>/dev/null); then
+            echo "::warning::Failed to check release ruleset, assuming release in progress"
+            echo "release-in-progress=true" >> "$GITHUB_OUTPUT"
+            exit 0
+          fi
+          echo "release-in-progress=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"

Replace the hardcoded ruleset ID with a dynamic lookup by name to make the
workflow more robust. The improved script fetches the ruleset ID by name and
handles cases where the ruleset is not found.

.github/workflows/nightly.yml [47-49]

 run: |
-  ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
+  # Assumes the ruleset is named 'release'. Please update with the correct name.
+  RULESET_NAME="release"
+  RULESET_ID=$(gh api /repos/${{ github.repository }}/rulesets --jq --arg name "$RULESET_NAME" '.[] | select(.name == $name) | .id')
+
+  if [[ -z "$RULESET_ID" ]]; then
+    echo "Ruleset '$RULESET_NAME' not found. Assuming no release is in progress."
+    echo "releasing=false" >> "$GITHUB_OUTPUT"
+    exit 0
+  fi
+
+  ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/${RULESET_ID} --jq '.enforcement')
   echo "releasing=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"

[Suggestion processed]

Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies that using a hardcoded ID (11911909) is brittle and proposes a more robust solution to look up the ruleset by name, significantly improving the workflow's maintainability and resilience.

High
Learned
best practice
Fail safely on API errors
Suggestion Impact:The workflow step now runs with bash strict mode (`set -euo pipefail`) and explicitly handles `gh api` failures by emitting a warning and defaulting to "release in progress" (`release-in-progress=true`) instead of proceeding silently. It also renames the output key from `releasing` to `release-in-progress`.

code diff:

+        shell: bash
         run: |
-          ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
-          echo "releasing=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
+          set -euo pipefail
+          # Ruleset 11911909 is "Release In Progress Access" - see restrict-trunk.yml
+          if ! ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement' 2>/dev/null); then
+            echo "::warning::Failed to check release ruleset, assuming release in progress"
+            echo "release-in-progress=true" >> "$GITHUB_OUTPUT"
+            exit 0
+          fi
+          echo "release-in-progress=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"

Add shell strict mode and handle gh api failures/empty responses explicitly
(prefer a safe default such as “release in progress” on error) so the workflow
doesn’t silently proceed when the API call fails.

.github/workflows/nightly.yml [47-49]

 run: |
-  ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
-  echo "releasing=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
+  set -euo pipefail
 
+  ENFORCEMENT="$(gh api "/repos/${{ github.repository }}/rulesets/11911909" --jq '.enforcement' 2>/dev/null || true)"
+  if [[ -z "${ENFORCEMENT}" ]]; then
+    echo "releasing=true" >> "$GITHUB_OUTPUT"
+    exit 0
+  fi
+
+  echo "releasing=$([[ "${ENFORCEMENT}" == "active" ]] && echo true || echo false)" >> "$GITHUB_OUTPUT"
+

[Suggestion processed]

Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Add explicit validation and availability guards at integration boundaries (GitHub Actions contexts, environment variables, external APIs) and fail safely on missing/invalid data.

Low
Use boolean parsing for outputs

Treat release-in-progress as a boolean using fromJSON(...) to avoid
stringly-typed comparisons and make the conditional more robust.

.github/workflows/nightly.yml [53]

-if: (github.event.repository.fork == false) && (needs.check-release.outputs.release-in-progress != 'true') && (inputs.language == 'ruby' || inputs.language == 'all' || github.event_name == 'schedule')
+if: (github.event.repository.fork == false) && (!fromJSON(needs.check-release.outputs.release-in-progress)) && (inputs.language == 'ruby' || inputs.language == 'all' || github.event_name == 'schedule')
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why:
Relevant best practice - Validate and normalize boundary inputs/outputs to avoid brittle string comparisons and ambiguous truthiness in GitHub Actions expressions.

Low
General
unify output variable naming
Suggestion Impact:The commit updated the job output to reference `steps.check.outputs.release-in-progress` and changed the step to emit `release-in-progress=` instead of `releasing=`, aligning step and job output names as suggested (with additional hardening changes).

code diff:

     outputs:
-      release-in-progress: ${{ steps.check.outputs.releasing }}
+      release-in-progress: ${{ steps.check.outputs.release-in-progress }}
     steps:
       - name: Check if release ruleset is active
         id: check
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        shell: bash
         run: |
-          ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
-          echo "releasing=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
+          set -euo pipefail
+          # Ruleset 11911909 is "Release In Progress Access" - see restrict-trunk.yml
+          if ! ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement' 2>/dev/null); then
+            echo "::warning::Failed to check release ruleset, assuming release in progress"
+            echo "release-in-progress=true" >> "$GITHUB_OUTPUT"
+            exit 0
+          fi
+          echo "release-in-progress=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"

Align the step output variable name with the job output variable name for better
clarity. Change the step's output from releasing to release-in-progress.

.github/workflows/nightly.yml [40-41]

+- name: Check if release ruleset is active
+  id: check
+  env:
+    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+  run: |
+    ENFORCEMENT=$(gh api /repos/${{ github.repository }}/rulesets/11911909 --jq '.enforcement')
+    echo "release-in-progress=$([[ "$ENFORCEMENT" == "active" ]] && echo 'true' || echo 'false')" >> "$GITHUB_OUTPUT"
+
 outputs:
-  release-in-progress: ${{ steps.check.outputs.releasing }}
+  release-in-progress: ${{ steps.check.outputs.release-in-progress }}

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 4

__

Why: This is a valid suggestion that improves code clarity and consistency by aligning the step output name (releasing) with the job output name (release-in-progress), making the workflow easier to read and understand.

Low
  • Update

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 prevents nightly releases from running while a release is in progress by adding a pre-check job that queries the GitHub API to determine if the release ruleset is active. If active, all language-specific nightly build jobs are skipped.

Changes:

  • Added a new check-release job that queries the release ruleset status via GitHub API
  • Updated all six language build jobs (ruby, python, java, dotnet, grid, javascript) to depend on the check-release job and skip execution when a release is in progress

@titusfortner titusfortner merged commit 1b5801b into trunk Jan 19, 2026
20 checks passed
@titusfortner titusfortner deleted the pr/nightly-prevent-conflicts branch January 19, 2026 18:17
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