Skip to content

[build] simplify release.yml: remove draft, build once during publish#16960

Merged
titusfortner merged 4 commits intotrunkfrom
simplify-release-yml
Jan 20, 2026
Merged

[build] simplify release.yml: remove draft, build once during publish#16960
titusfortner merged 4 commits intotrunkfrom
simplify-release-yml

Conversation

@titusfortner
Copy link
Member

@titusfortner titusfortner commented Jan 20, 2026

User description

🔗 Related Issues

Changes in #16955 allow us to simplify release process. Currently building twice once for upload and once for release.

💥 What does this PR do?

  • Move approval to the beginning, so nothing happens until approval
  • Build and publish in one bazel job
  • Do not need a draft github release, just download generated assets and do the release

Old flow:

prepare → build (all) → create-draft-release → get-approval → publish (each) → finalize-release → ...

New flow:

prepare → get-approval → publish (each, includes build) → github-release → ...

🔧 Implementation Notes

Also removed unnecessary checkouts
Not differentiating between build and publish, but step names and logging info will tell us where problems are

💡 Additional Considerations

  • Won't be able to test this until the next actual release

🔄 Types of changes

  • Cleanup (formatting, renaming)

PR Type

Enhancement


Description

  • Reorganize workflow to build and publish in single job

  • Move approval step before build to gate release process

  • Remove draft release creation, create final release directly

  • Eliminate unnecessary checkout and duplicate build steps

  • Download language-specific artifacts for final release


Diagram Walkthrough

flowchart LR
  prepare["Prepare Release"]
  approval["Get Approval"]
  publish["Publish (Build + Release)"]
  github["GitHub Release"]
  verify["Verify"]
  docs["Update Docs"]
  
  prepare -- "tag, version" --> approval
  approval -- "approved" --> publish
  publish -- "artifacts" --> github
  github --> verify
  docs --> verify
Loading

File Walkthrough

Relevant files
Configuration changes
release.yml
Consolidate build and publish, streamline approval workflow

.github/workflows/release.yml

  • Reorganized job dependencies: moved get-approval before publish to
    gate the release process
  • Consolidated build and publish jobs into single publish job that
    builds and releases per language
  • Removed create-release draft job; github-release now creates final
    release directly
  • Removed unnecessary checkout from prepare job and unused permissions
  • Updated github-release to download language-specific artifacts and
    removed draft/update flags
  • Renamed version reset jobs for clarity: "Generate Version Reset" →
    "Generate Nightly Versions"
  • Removed duplicate github-release finalization job that was updating
    draft to release
+35/-64 

@selenium-ci selenium-ci added the B-build Includes scripting, bazel and CI integrations label Jan 20, 2026
@titusfortner titusfortner requested a review from Copilot January 20, 2026 16:13
@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
🟢
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: 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: 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: Comprehensive Audit Trails

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

Status:
Audit trail coverage: The workflow performs critical release actions (publish and GitHub release creation) but
the diff does not show explicit, structured audit logging capturing actor, action, and
outcome beyond default GitHub Actions logs.

Referred Code
get-approval:
  name: Get Approval
  needs: prepare
  uses: ./.github/workflows/get-approval.yml
  with:
    title: Release approval required
    message: Approval is needed to publish ${{ needs.prepare.outputs.tag }}.
  secrets:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

publish:
  name: Build and Publish ${{ matrix.language }}
  needs: get-approval
  strategy:
    fail-fast: false
    matrix:
      language: [java, py, rb, dotnet, node]
  uses: ./.github/workflows/bazel.yml
  with:
    name: Publish ${{ matrix.language }}
    gpg-sign: ${{ matrix.language == 'java' }}


 ... (clipped 43 lines)

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:
Limited failure context: Several critical shell/CLI operations (e.g., gh release delete, git push --delete) rely on
default step failure behavior and do not add explicit, actionable error context for edge
cases beyond silent >/dev/null checks.

Referred Code
- name: Delete nightly release and tag
  env:
    GH_TOKEN: ${{ secrets.SELENIUM_CI_TOKEN }}
  run: |
    if gh release view nightly >/dev/null 2>&1; then
      gh release delete nightly --yes
    fi
    if git ls-remote --tags origin refs/tags/nightly | grep -q nightly; then
      git push origin --delete refs/tags/nightly
    fi

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:
Secrets in workflow: The workflow uses sensitive tokens via secrets/GH_TOKEN, and while they are not directly
echoed in the diff, confirming that no downstream steps or reusable workflows log
secret-derived values requires review outside this diff.

Referred Code
publish:
  name: Build and Publish ${{ matrix.language }}
  needs: get-approval
  strategy:
    fail-fast: false
    matrix:
      language: [java, py, rb, dotnet, node]
  uses: ./.github/workflows/bazel.yml
  with:
    name: Publish ${{ matrix.language }}
    gpg-sign: ${{ matrix.language == 'java' }}
    run: ./go ${{ matrix.language }}:release
    artifact-name: release-packages-${{ matrix.language }}
    artifact-path: build/dist/*.*
  secrets: inherit

github-release:
  name: GitHub Release
  needs: [prepare, publish]
  runs-on: ubuntu-latest
  permissions:


 ... (clipped 28 lines)

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 0c7a1ec

CategorySuggestion                                                                                                                                    Impact
Incremental [*]
Avoid overwriting existing release metadata

Add omitBodyDuringUpdate: true and omitNameDuringUpdate: true to the
release-action step to prevent overwriting the release name and body on
subsequent updates.

.github/workflows/release.yml [102]

 allowUpdates: true
+omitBodyDuringUpdate: true
+omitNameDuringUpdate: true
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This is an excellent suggestion that identifies a regression, as the proposed options existed in the old workflow but were omitted in the refactoring, thus preventing accidental overwrites of release notes.

Medium
Guard commit selection for non-PR runs

Guard access to github.event.pull_request.merge_commit_sha to ensure the
workflow runs correctly for non-PR triggers like workflow_dispatch.

.github/workflows/release.yml [108]

-commit: ${{ github.event.pull_request.merge_commit_sha || github.sha }}
+commit: "${{ (github.event.pull_request && github.event.pull_request.merge_commit_sha) || github.sha }}"
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that accessing github.event.pull_request without a guard can cause errors on non-PR triggers like workflow_dispatch, and the proposed fix makes the workflow more robust.

Medium
Prevent failing on missing tags

Make the nightly tag deletion step idempotent by adding || true to the gh api
command to prevent workflow failure if the tag is already gone.

.github/workflows/release.yml [97]

-gh api -X DELETE /repos/${{ github.repository }}/git/refs/tags/nightly
+gh api -X DELETE /repos/${{ github.repository }}/git/refs/tags/nightly || true
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a potential race condition and proposes a simple fix to make the tag deletion step more robust, preventing potential workflow failures.

Low
Possible issue
Verify artifact-path parameter compatibility

Verify that the reusable workflow bazel.yml uses the artifact-path parameter
passed in the publish job, and remove it if it is unused.

.github/workflows/release.yml [57-71]

 publish:
   name: Build and Publish ${{ matrix.language }}
   needs: get-approval
   strategy:
     fail-fast: false
     matrix:
       language: [java, py, rb, dotnet, node]
   uses: ./.github/workflows/bazel.yml
   with:
     name: Publish ${{ matrix.language }}
     gpg-sign: ${{ matrix.language == 'java' }}
     run: ./go ${{ matrix.language }}:release
     artifact-name: release-packages-${{ matrix.language }}
-    artifact-path: build/dist/*.*
   secrets: inherit
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a potential issue where the artifact-path parameter might not be used by the reusable bazel.yml workflow, making it redundant. It rightly asks to verify its usage, which is a good practice for maintainability and clarity.

Low
  • More

Previous suggestions

✅ Suggestions up to commit 27f00a4
CategorySuggestion                                                                                                                                    Impact
Possible issue
Use correct release commit SHA
Suggestion Impact:The workflow's release action "commit" input was changed from github.sha to use github.event.pull_request.merge_commit_sha with a fallback to github.sha, aligning the release tag with the PR merge commit when available.

code diff:

-          commit: "${{ github.sha }}"
+          commit: ${{ github.event.pull_request.merge_commit_sha || github.sha }}
 

Use the pull request's merge_commit_sha for PR-triggered runs to ensure the
release tag points to the correct commit, falling back to github.sha for other
event types.

.github/workflows/release.yml [109]

-commit: "${{ github.sha }}"
+commit: "${{ github.event_name == 'pull_request' && github.event.pull_request.merge_commit_sha || github.sha }}"

[Suggestion processed]

Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies that github.sha points to the PR's head commit, not the merge commit, which is critical for creating a release tag that accurately reflects the state of the default branch after the merge.

High
Incremental [*]
Make release creation idempotent
Suggestion Impact:The workflow was updated to set `allowUpdates: true` for the release-action step, making release creation idempotent on re-runs.

code diff:

-          allowUpdates: ${{ github.run_attempt > 1 }}
+          allowUpdates: true
           artifacts: "build/dist/*.*"

Set allowUpdates: true to prevent workflow failures on re-runs if a release
already exists, making the job idempotent.

.github/workflows/release.yml [103]

-allowUpdates: ${{ github.run_attempt > 1 }}
+allowUpdates: true

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly points out a potential failure scenario on re-runs and proposes a change to make the release creation step more robust and idempotent.

Medium
Avoid persisting Git credentials
Suggestion Impact:The checkout step was changed to use persist-credentials: false (and the explicit token line was removed), reducing persisted Git credential exposure as suggested.

code diff:

       - name: Checkout repo
         uses: actions/checkout@v4
         with:
-          token: ${{ secrets.SELENIUM_CI_TOKEN }}
-          persist-credentials: true
+          persist-credentials: false

Set persist-credentials: false in the checkout action and only authenticate when
needed to reduce the exposure of secrets.

.github/workflows/release.yml [82-84]

 with:
   token: ${{ secrets.SELENIUM_CI_TOKEN }}
-  persist-credentials: true
+  persist-credentials: false

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a security best practice to limit credential exposure, which is relevant as a later step performs a git push.

Medium
✅ Suggestions up to commit b9e2a03
CategorySuggestion                                                                                                                                    Impact
Possible issue
Use consistent credentials for tag deletion
Suggestion Impact:The workflow's checkout step was updated to use the SELENIUM_CI_TOKEN and to persist credentials, aligning git operations (like tag deletion) with the token used by gh commands.

code diff:

       - name: Checkout repo
         uses: actions/checkout@v4
+        with:
+          token: ${{ secrets.SELENIUM_CI_TOKEN }}
+          persist-credentials: true

Configure the actions/checkout step to use the SELENIUM_CI_TOKEN and persist
credentials. This ensures both gh and git commands have consistent and
sufficient permissions to prevent failures when deleting tags.

.github/workflows/release.yml [80-97]

 - name: Checkout repo
   uses: actions/checkout@v4
+  with:
+    token: ${{ secrets.SELENIUM_CI_TOKEN }}
+    persist-credentials: true
 - name: Delete nightly release and tag
   env:
     GH_TOKEN: ${{ secrets.SELENIUM_CI_TOKEN }}
   run: |
     if gh release view nightly >/dev/null 2>&1; then
       gh release delete nightly --yes
     fi
     if git ls-remote --tags origin refs/tags/nightly | grep -q nightly; then
       git push origin --delete refs/tags/nightly
     fi
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a potential permissions issue where git push --delete might fail because it uses the default GITHUB_TOKEN, unlike the gh commands which use a privileged SELENIUM_CI_TOKEN. This change is critical for the release workflow's reliability.

High
Incremental [*]
Restrict release updates to reruns
Suggestion Impact:Updated the release-action configuration to only allow release updates when the workflow is a rerun (run_attempt > 1), matching the suggested security enhancement.

code diff:

       - name: Create GitHub release
         uses: ncipollo/release-action@v1
         with:
-          allowUpdates: true
+          allowUpdates: ${{ github.run_attempt > 1 }}
           artifacts: "build/dist/*.*"

Change allowUpdates: true to allowUpdates: ${{ github.run_attempt > 1 }} to
restrict release updates to only occur on workflow reruns.

.github/workflows/release.yml [101]

-allowUpdates: true
+allowUpdates: ${{ github.run_attempt > 1 }}

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: This is a valuable security enhancement that prevents accidental overwrites of a release, only allowing updates on job reruns, which is a safer operational practice.

Medium
✅ Suggestions up to commit 446402f
CategorySuggestion                                                                                                                                    Impact
Possible issue
Download all packages for release
Suggestion Impact:The workflow was changed from two separate artifact downloads (java and dotnet) to a single download-artifact step that pulls all release-packages-* artifacts into build/dist (using pattern + merge-multiple). An additional allowUpdates flag was also added to the release step, but the primary change matches the suggestion’s intent.

code diff:

-      - name: Download Java packages
+      - name: Download release packages
         uses: actions/download-artifact@v4
         with:
-          name: release-packages-java
-      - name: Download .NET packages
-        uses: actions/download-artifact@v4
-        with:
-          name: release-packages-dotnet
+          pattern: release-packages-*
           path: build/dist
+          merge-multiple: true

Modify the github-release job to download all release packages into the
build/dist directory by using a single download-artifact step without a specific
artifact name.

.github/workflows/release.yml [82-90]

-- name: Download Java packages
+- name: Download all release packages
   uses: actions/download-artifact@v4
   with:
-    name: release-packages-java
-- name: Download .NET packages
-  uses: actions/download-artifact@v4
-  with:
-    name: release-packages-dotnet
     path: build/dist

[Suggestion processed]

Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical bug where the release would be incomplete, as it only downloads a subset of packages and places one in the wrong directory. The proposed fix is correct and efficient.

High
Learned
best practice
Make release creation rerunnable
Suggestion Impact:The workflow's "Create GitHub release" step was updated to include `allowUpdates: true`, making the release action tolerate an existing release and enabling reruns. The additional suggested omit* update options were not added.

code diff:

       - name: Create GitHub release
         uses: ncipollo/release-action@v1
         with:
+          allowUpdates: true
           artifacts: "build/dist/*.*"
           bodyFile: "scripts/github-actions/release_header.md"
           generateReleaseNotes: true

Make the release step safe to re-run by allowing updates or skipping when the
release already exists, to avoid failures when the tag/release is present from a
partial run.

.github/workflows/release.yml [101-109]

 - name: Create GitHub release
   uses: ncipollo/release-action@v1
   with:
     artifacts: "build/dist/*.*"
     bodyFile: "scripts/github-actions/release_header.md"
     generateReleaseNotes: true
     name: "Selenium ${{ needs.prepare.outputs.version }}"
     tag: "${{ needs.prepare.outputs.tag }}"
     commit: "${{ github.sha }}"
+    allowUpdates: true
+    omitBodyDuringUpdate: true
+    omitNameDuringUpdate: true

[Suggestion processed]

Suggestion importance[1-10]: 5

__

Why:
Relevant best practice - Make lifecycle-sensitive automation robust and idempotent so reruns/retries do not fail due to already-created resources.

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 simplifies the Selenium release workflow by consolidating the build and publish steps into a single operation, moving approval earlier in the process, and eliminating the draft GitHub release stage.

Changes:

  • Moved approval step before building/publishing to gate the entire release process
  • Consolidated build and publish into single per-language jobs that both build and release artifacts
  • Removed draft GitHub release creation; now creates final release directly with artifacts

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 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 1 out of 1 changed files in this pull request and generated no new 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 1 out of 1 changed files in this pull request and generated 1 comment.

This was referenced Feb 22, 2026
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 3/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants