Skip to content

Conversation

@shichengripple001
Copy link
Collaborator

High Level Overview of Change

1, Workflow needs to be triggered from main branch for both beta and stable release
2, For stable release, A PR from release branch to main branch is required before triggering the release pipeline
3, Security champion(Chenna and Cheng) are added to Security reviewers. Beta sec review will be done by Security champion.
4, "-experimental" will automatically appended to dist tag for beta release
5, Tests are allowed to fail for beta release

Context of Change

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

Did you update HISTORY.md?

  • Yes
  • No, this change does not impact library users

Test Plan

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Walkthrough

The pull request modifies .github/workflows/release.yml to introduce a required release_branch_name input, adds multiple job outputs, reworks npm dist-tag handling for beta and stable releases, implements PR validation, and adjusts downstream jobs to use the new outputs and conditional flows accordingly.

Changes

Cohort / File(s) Summary
Release Workflow Enhancement
.github/workflows/release.yml
Adds release_branch_name input; introduces get_version job outputs (dist_tag, npm_is_beta, release_branch, release_pr_number, release_pr_url, is_beta); implements beta/stable release path logic with PR validation; updates npm tagging, release publishing, and Slack notifications; adds new jobs for documentation generation and failure notification; refactors downstream job refs and conditionals to use new outputs.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Key areas requiring attention:
    • Beta vs stable release path logic and conditionals (is_beta propagation through workflow)
    • PR validation logic for stable releases and PR URL/number extraction
    • npm dist-tag handling and package version compatibility enforcement
    • Output propagation from get_version job to downstream steps and jobs
    • New job orchestration (generate-documentation, notify_failures) and their dependencies
    • Slack notification message construction using new variables and PR links
    • Tag creation and release publishing conditional flow based on is_beta flag

Possibly related PRs

Suggested reviewers

  • achowdhry-ripple
  • pdp2121
  • ckeshava
  • sguntaka1578-ripple
  • Patel-Raj11

Poem

🐰 A workflow transformed, so grand and so bright,
Beta paths shimmer, stable paths take flight,
PR validations dance through the night,
With dist-tags aplenty, the release feels right,
Notifications cascade in Slack's gentle light!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Beta release workflow' is partially related to the changeset but misses the main point: this PR fundamentally restructures the release workflow to support BOTH beta and stable releases with new requirements (PR-based stable releases, branch-based triggering, security reviewer updates). The title only highlights beta features. Revise title to reflect the core change: e.g., 'Add beta and stable release workflow with PR-based promotions' or 'Restructure release workflow to support beta and stable paths with PR requirements'.
Description check ❓ Inconclusive The description provides the high-level overview of changes but lacks critical details: no context explaining why this redesign was needed, no test plan describing how the workflow changes were validated, and no indication of HISTORY.md updates. The 'Type of Change' checkboxes and other template sections remain empty. Add context explaining the motivation for this workflow redesign, provide a detailed test plan showing how beta/stable paths and security flows were verified, and clarify HISTORY.md update status.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/release.yml (1)

513-513: Unclear logical AND in PACKAGE_NAME assignment.

Line 513 uses needs.get_version.outputs.package_version && github.event.inputs.package_name, which employs a logical AND to conditionally select the package name. This is confusing and suggests unintended logic—the expression will return the package name only if package_version is truthy. Simplify to directly reference the input or output:

-         PACKAGE_NAME: ${{ needs.get_version.outputs.package_version && github.event.inputs.package_name }}
+         PACKAGE_NAME: ${{ github.event.inputs.package_name }}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f128b7 and 963af92.

📒 Files selected for processing (1)
  • .github/workflows/release.yml (17 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: mvadari
Repo: XRPLF/xrpl.js PR: 2788
File: .github/workflows/nodejs.yml:25-25
Timestamp: 2024-09-26T21:14:56.813Z
Learning: In `.github/workflows/nodejs.yml`, the `build-and-lint` job's actions `actions/setup-node` and `actions/cache` are updated to `v4`.
📚 Learning: 2025-10-09T20:16:27.834Z
Learnt from: ckeshava
Repo: XRPLF/xrpl.js PR: 3101
File: .github/workflows/nodejs.yml:220-221
Timestamp: 2025-10-09T20:16:27.834Z
Learning: In `.github/workflows/nodejs.yml`, the `generate-documentation` job intentionally uses `if: startsWith(github.ref, 'refs/tags/xrpl@')` instead of `env.GIT_REF` to ensure documentation is only generated and deployed on actual tag push events, not when the workflow is called via `workflow_call` with a tag reference.

Applied to files:

  • .github/workflows/release.yml
📚 Learning: 2024-09-26T21:14:56.813Z
Learnt from: mvadari
Repo: XRPLF/xrpl.js PR: 2788
File: .github/workflows/nodejs.yml:25-25
Timestamp: 2024-09-26T21:14:56.813Z
Learning: In `.github/workflows/nodejs.yml`, the `build-and-lint` job's actions `actions/setup-node` and `actions/cache` are updated to `v4`.

Applied to files:

  • .github/workflows/release.yml
🔇 Additional comments (9)
.github/workflows/release.yml (9)

12-14: New input and outputs are well-structured.

The addition of release_branch_name as a required input and the new outputs (dist_tag, npm_is_beta, release_branch, release_pr_number, release_pr_url, is_beta) establish a clear contract for downstream jobs.

Also applies to: 29-34


42-143: Comprehensive input validation with proper guards.

The validate_inputs step correctly handles package name validation, security checks (Artifactory URL), dist tag normalization & validation, branch requirements for stable releases, and PR existence checks for stable releases. The use of gh api for PR validation is appropriate.


176-176: Consistent use of release_branch output across jobs.

All downstream jobs correctly reference needs.get_version.outputs.release_branch for checkout and git refs.

Also applies to: 184-184, 202-202


189-189: Test failure bypass for beta releases is correctly implemented.

The conditional logic across pre_release, ask_for_dev_team_review, first_review, ask_for_sec_team_review, and release jobs properly allows test failures for beta releases (when is_beta == 'true') while requiring success for stable releases. This aligns with the PR objective.

Also applies to: 351-351, 491-491, 503-503, 533-533


382-382: PR_URL outputs are correctly referenced.

The new release_pr_url output is consistently used across jobs and properly incorporated into Slack notifications.

Also applies to: 435-435, 472-472


550-599: Release job correctly validates and publishes with appropriate flags.

The publish step properly validates the package.json, enforces semantic versioning for stable releases, and uses the correct npm dist-tag. The GitHub release creation correctly sets prerelease and make_latest flags based on the is_beta output.

Also applies to: 626-627


664-716: Failure aggregation logic correctly distinguishes beta and stable failures.

The notify_failures job properly evaluates which failures should trigger notifications, allowing test failures for beta releases while requiring success for stable releases. The conditional logic is well-structured and the Slack notification lists failed job names.


212-212: Typo fix confirmed.

The comment on line 212 correctly uses "debugging" (previously "dubugging").


145-170: ****

The review comment misunderstands how GitHub Actions environment variables work. Environment variables set via GITHUB_ENV are available to all processes in following steps of the same job. Since both validate_inputs and get_version are steps within the same get_version job, the NPM_DIST_TAG variable set in validate_inputs is automatically available to get_version. The code is correct as-is and requires no changes.

Likely an incorrect or invalid review comment.

PACKAGE_VERSION: "${{ needs.get_version.outputs.package_version }}"
PACKAGE_NAME: "${{ github.event.inputs.package_name }}"
RELEASE_BRANCH: "${{ github.ref_name }}"
RELEASE_BRANCH: "${{ github.event.inputs.release_branch_name }}"
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Use release_branch output instead of input for consistency.

Line 359 references github.event.inputs.release_branch_name directly, but the release_branch output from get_version is the validated and canonical value. For consistency with other jobs, use needs.get_version.outputs.release_branch.

    env:
      PACKAGE_VERSION: "${{ needs.get_version.outputs.package_version }}"
      PACKAGE_NAME: "${{ github.event.inputs.package_name }}"
-     RELEASE_BRANCH: "${{ github.event.inputs.release_branch_name }}"
+     RELEASE_BRANCH: "${{ needs.get_version.outputs.release_branch }}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RELEASE_BRANCH: "${{ github.event.inputs.release_branch_name }}"
env:
PACKAGE_VERSION: "${{ needs.get_version.outputs.package_version }}"
PACKAGE_NAME: "${{ github.event.inputs.package_name }}"
RELEASE_BRANCH: "${{ needs.get_version.outputs.release_branch }}"
🤖 Prompt for AI Agents
.github/workflows/release.yml around line 359: the workflow is using
github.event.inputs.release_branch_name directly; replace that reference with
the validated output from the get_version job by setting RELEASE_BRANCH to
needs.get_version.outputs.release_branch so the job consumes the canonical,
validated branch value consistent with other jobs.

Comment on lines +652 to +662
generate-documentation:
name: Generate and Publish documentation for ${{ needs.get_version.outputs.package_version }}
if: ${{ needs.get_version.outputs.is_beta != 'true' }}
uses: ./.github/workflows/generate-documentation.yml
needs: [get_version, release]
permissions:
contents: read
pages: write
id-token: write
with:
git_ref: ${{ github.ref_name }}
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 10, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

generate-documentation job uses incorrect git_ref.

Line 662 uses git_ref: ${{ github.ref_name }}, which for a workflow_dispatch event refers to the current branch (typically main), not the release branch. Documentation should be generated from the released code. Consider using the release tag or branch instead:

  generate-documentation:
    name: Generate and Publish documentation for ${{ needs.get_version.outputs.package_version }}
    if: ${{ needs.get_version.outputs.is_beta != 'true' }}
    uses: ./.github/workflows/generate-documentation.yml
    needs: [get_version, release]
    permissions:
      contents: read
      pages: write
      id-token: write
    with:
-     git_ref: ${{ github.ref_name }}
+     git_ref: ${{ needs.get_version.outputs.release_branch }}

Alternatively, if documentation should be generated from the tag, use the tag name from the release job output (e.g., ${{ needs.release.outputs.tag_name }}).

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/release.yml lines 652-662: the generate-documentation job is
using git_ref: ${{ github.ref_name }}, which for workflow_dispatch resolves to
the current branch (usually main) instead of the released commit/tag; replace
the git_ref with the release job's tag or branch (for example use ${{
needs.release.outputs.tag_name }} or the release commit/branch output you have)
so the documentation job checks out the actual released code; update the
with.git_ref value accordingly and ensure the release job is listed in needs so
that its output is available.

Copy link
Collaborator

Choose a reason for hiding this comment

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

^^ @shichengripple001 can you please update the git_ref variable? I wrote the generate-documentation workflow based on the current version of the release workflow.

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

TAG="latest"
echo "ℹ️ npmjs_dist_tag empty → defaulting to 'latest'."
else
TAG="$(printf '%s' "$RAW_DIST_TAG" | tr -d '[:space:]')"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
TAG="$(printf '%s' "$RAW_DIST_TAG" | tr -d '[:space:]')"
TAG="$(printf '%s' "$RAW_DIST_TAG" | tr -d '[:blank:]')"

nit: This removes both spaces and tabs from the inputs, whereas :space: does not recognize tab characters.

NPM_DIST_TAG="latest"
fi
if [[ "$NPM_DIST_TAG" == "latest" ]] && ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
NPM_DIST_TAG="${NPM_DIST_TAG:-latest}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this step necessary? NPM_DIST_TAG is already written into GITHUB_ENV in lines 109-112 (get_version.steps.validate_inputs section) of this updated file.


pre_release:
runs-on: ubuntu-latest
if: ${{ always() && needs.get_version.result == 'success' && (needs.run_faucet_test.result == 'success' || needs.get_version.outputs.is_beta == 'true') && (needs.run_tests.result == 'success' || needs.get_version.outputs.is_beta == 'true') }}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if: ${{ always() && needs.get_version.result == 'success' && (needs.run_faucet_test.result == 'success' || needs.get_version.outputs.is_beta == 'true') && (needs.run_tests.result == 'success' || needs.get_version.outputs.is_beta == 'true') }}
if: ${{ needs.get_version.result == 'success' && (needs.run_faucet_test.result == 'success' || needs.get_version.outputs.is_beta == 'true') && (needs.run_tests.result == 'success' || needs.get_version.outputs.is_beta == 'true') }}

Since there are other conditional expressions, always() is not useful in this context.

- name: Generate CycloneDX SBOM
run: cyclonedx-npm --output-format json --output-file sbom.json

- name: Scan SBOM for vulnerabilities using Trivy
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hypothetically, suppose that there are SBOM vulnerabilities reported for a beta release. Do we have a policy for accepting/rejecting the beta-release, for the role of the security champion? What are the tolerable types of SBOM vulnerabilities?

- name: Print scan report
run: cat vuln-report.txt

- name: Upload vulnerability report artifact
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we increase the retention policy for these uploaded vulnerability-report artifacts? I believe the default is 10 days, however a 30-day period is useful to perform retroactive analysis.


ask_for_dev_team_review:
runs-on: ubuntu-latest
if: ${{ always() && needs.pre_release.result == 'success' && (needs.run_tests.result == 'success' || needs.get_version.outputs.is_beta == 'true') }}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if: ${{ always() && needs.pre_release.result == 'success' && (needs.run_tests.result == 'success' || needs.get_version.outputs.is_beta == 'true') }}
if: ${{ needs.pre_release.result == 'success' && (needs.run_tests.result == 'success' || needs.get_version.outputs.is_beta == 'true') }}

Comment on lines +652 to +662
generate-documentation:
name: Generate and Publish documentation for ${{ needs.get_version.outputs.package_version }}
if: ${{ needs.get_version.outputs.is_beta != 'true' }}
uses: ./.github/workflows/generate-documentation.yml
needs: [get_version, release]
permissions:
contents: read
pages: write
id-token: write
with:
git_ref: ${{ github.ref_name }}
Copy link
Collaborator

Choose a reason for hiding this comment

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

^^ @shichengripple001 can you please update the git_ref variable? I wrote the generate-documentation workflow based on the current version of the release workflow.

run: |
MESSAGE="❌ Release failed for ${{ env.PACKAGE_NAME }}@${{ env.PACKAGE_VERSION }}. Check the logs: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
curl -X POST https://slack.com/api/chat.postMessage \
set -euo pipefail
Copy link
Collaborator

Choose a reason for hiding this comment

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

The notify_failures job is not pinned to run on any specific shell. However, the pipefail option is configured to work only on bash and ksh shells. It will not work on dash (or) sh shells.

Discussion: https://askubuntu.com/questions/886537/set-e-o-pipefail-not-working-on-bash-script-on-ubuntu-16

Some of the jobs in this workflow use bash as the pinned shell, is that sufficient for all the jobs?

IS_BETA="false"
else
IS_BETA="true"
TAG="${TAG}-experimental"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we do TAG="${TAG}-beta" instead?

TAG="${TAG}-experimental"
fi
if [ "$IS_BETA" != "true" ] && [[ ! "${RELEASE_BRANCH,,}" =~ ^release[-/] ]]; then
Copy link
Collaborator

@kuan121 kuan121 Nov 14, 2025

Choose a reason for hiding this comment

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

Can we also validate branch name for beta release to ensure that the branch is main? I don't think we want people to release beta using any branch.

on:
workflow_dispatch:
inputs:
package_name:
Copy link
Collaborator

@kuan121 kuan121 Nov 14, 2025

Choose a reason for hiding this comment

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

1, Workflow needs to be triggered from main branch for both beta and stable release
2, For stable release, A PR from release branch to main branch is required before triggering the release pipeline

Why do we want to check that a PR to merge release-xxx into main exists? Can we still automatically create a PR to merge release-xxx into main for stable release?

5, Tests are allowed to fail for beta release

If test failures are acceptable, can we skip the test steps entirely for beta releases? What value do the tests provide in this case?

package_name:
description: 'Package folder (Name of the package directory under packages/ folder. e.g., xrpl, ripple-address-codec)'
required: true
release_branch_name:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you update https://github.com/XRPLF/xrpl.js/blob/main/RELEASE.md to reflect the final release process before you merge this PR?

if [ -z "$NPM_DIST_TAG" ]; then
NPM_DIST_TAG="latest"
# validate dist tag(s)
RAW_DIST_TAG="${{ github.event.inputs.npmjs_dist_tag }}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

FYI - #3133, we need to use env vars.

set -euo pipefail
MSG="${EXECUTOR} is releasing ${PACKAGE_NAME}@${PACKAGE_VERSION}. A member from the infosec team (${SEC_REVIEWERS}) needs to take the following action:\n Review the release artifacts and approve/reject the release. (${RUN_URL})"
MSG="${EXECUTOR} is releasing ${PACKAGE_NAME}@${PACKAGE_VERSION}. A sec reviewer from (${SEC_REVIEWERS}) needs to take the following action:\nReview the release artifacts and approve/reject the release. (${RUN_URL})"
Copy link
Collaborator

Choose a reason for hiding this comment

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

3, Security champion(Chenna and Cheng) are added to Security reviewers. Beta sec review will be done by Security champion.

For the beta release, will ${SEC_REVIEWERS} include Infosec members? They may find it confusing or inconvenient to be mentioned in the Slack notification when they don’t actually need to review beta releases. Would it make sense to use a separate notification mechanism, or maintain two security reviewer lists—one for stable releases and another for beta?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants