From 2b5a84b58f67b1d486d28e9d5506f6e6dff42d19 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Tue, 24 Mar 2026 14:31:28 -0600 Subject: [PATCH 1/8] fix(sdk): enforce single source of truth for SDK package versioning (#35109) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add core-web/libs/sdk/VERSION as the single version source - Replace ~150 lines of fragile NPM-scanning version detection with a simple read from VERSION file - Use GITHUB_RUN_NUMBER as next tag suffix — guaranteed unique, no collision - Manual release workflow now bumps VERSION file and commits it to git - New packages added to libs/sdk/ work automatically without manual sync Fixes recurring 403 publish failures caused by packages drifting out of version sync (e.g. react at 1.2.6-next.3 while others at 1.2.5-next.7). Co-Authored-By: Claude Sonnet 4.6 --- .../deploy-javascript-sdk/action.yml | 689 +++--------------- .../workflows/cicd_manual-release-sdks.yml | 45 +- core-web/libs/sdk/VERSION | 1 + 3 files changed, 150 insertions(+), 585 deletions(-) create mode 100644 core-web/libs/sdk/VERSION diff --git a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml index d36148cb38a9..5451c4debc4d 100644 --- a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml +++ b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml @@ -1,15 +1,9 @@ -# Note: This action publishes stable versions of the SDK libraries to NPM. -# -# DUAL PUBLISHING BEHAVIOR: -# LATEST TAG: -# - If current version contains "alpha" or "beta" -> publishes 1.0.0 -# - If stable version exists -> publishes on explicit version-type (patch/minor/major/custom) -# - Auto mode with stable version -> skips latest publishing (no version change) +# Note: This action publishes SDK libraries to NPM. # -# NEXT TAG: -# - Always publishes with "-next.X" suffix where X increments -# - If transitioning from prerelease -> publishes {latest_version}-next.1 -# - If stable version -> publishes {current_or_new_version}-next.{incremented_patch} +# VERSIONING: +# - Single source of truth: core-web/libs/sdk/VERSION file +# - LATEST TAG: published only when version-type != 'auto' (manual releases) +# - NEXT TAG: always published on trunk runs, suffix = GITHUB_RUN_NUMBER (unique, no collision) # name: 'SDK Publish NPM Packages - Stable' description: 'Publish stable versions of the dotCMS SDK libs on NPM registry.' @@ -26,7 +20,7 @@ inputs: required: false default: 'latest' version-type: - description: 'Version type: auto (default), patch, minor, major, or custom. Auto means no increment unless transitioning from prerelease to 1.0.0' + description: 'Version type: auto (default), patch, minor, major, or custom. Auto means no increment — publishes next tag only.' required: false default: 'auto' custom-version: @@ -42,7 +36,7 @@ outputs: value: ${{ steps.deployment_status.outputs.npm_package_version }} npm-package-version-next: description: 'SDK libs - NPM package version for next tag' - value: ${{ steps.next_version.outputs.next_version_next }} + value: ${{ steps.set_versions.outputs.next_version_next }} published-latest: description: 'SDK libs - Published to latest tag' value: ${{ steps.deployment_status.outputs.published_latest }} @@ -54,7 +48,7 @@ outputs: value: ${{ steps.deployment_status.outputs.published }} version-type-used: description: 'Type of version increment that was applied' - value: ${{ steps.next_version.outputs.version_type_used }} + value: ${{ steps.set_versions.outputs.version_type_used }} runs: using: "composite" steps: @@ -85,542 +79,116 @@ runs: echo "::endgroup::" shell: bash - - name: 'Detect SDK packages and check NPM status' - id: current_version + - name: 'Set versions from VERSION file' + id: set_versions working-directory: ${{ github.workspace }}/core-web/libs/sdk/ - run: | - echo "::group::Detect SDK packages and check NPM status" - - # Detect all SDK packages dynamically - sdk_packages=($(find . -maxdepth 1 -type d -exec basename {} \; | grep -v "^\.$")) - echo "Found SDK packages: ${sdk_packages[*]}" - - # Check the status of each package and find the highest version - HIGHEST_VERSION="0.0.0" - HIGHEST_NEXT_VERSION="" - VERSION_SOURCE="none" - PACKAGES_STATUS="" - - for sdk in "${sdk_packages[@]}"; do - echo "" - echo "🔍 Checking @dotcms/${sdk}..." - - # Check if package exists in NPM - if npm view @dotcms/${sdk} >/dev/null 2>&1; then - # Package exists, get current versions - STABLE_VERSION=$(npm view @dotcms/${sdk} dist-tags --json 2>/dev/null | jq -r '.latest // empty') - NEXT_VERSION=$(npm view @dotcms/${sdk} dist-tags --json 2>/dev/null | jq -r '.next // empty') - - echo " ✅ Package exists - Latest: ${STABLE_VERSION:-'none'}, Next: ${NEXT_VERSION:-'none'}" - - # Update highest version if this package has a higher stable version - if [ -n "$STABLE_VERSION" ] && [ "$STABLE_VERSION" != "null" ] && [ "$STABLE_VERSION" != "empty" ]; then - if [ "$STABLE_VERSION" != "0.0.0" ]; then - if [ "$HIGHEST_VERSION" = "0.0.0" ] || [ "$(printf '%s\n' "$STABLE_VERSION" "$HIGHEST_VERSION" | sort -V | tail -n1)" = "$STABLE_VERSION" ]; then - HIGHEST_VERSION="$STABLE_VERSION" - VERSION_SOURCE="existing" - fi - fi - fi - - # Track highest next version across packages - if [ -n "$NEXT_VERSION" ] && [ "$NEXT_VERSION" != "null" ] && [ "$NEXT_VERSION" != "empty" ]; then - if [ -z "$HIGHEST_NEXT_VERSION" ]; then - HIGHEST_NEXT_VERSION="$NEXT_VERSION" - else - # Compare next versions to find the highest - if [ "$(printf '%s\n' "$NEXT_VERSION" "$HIGHEST_NEXT_VERSION" | sort -V | tail -n1)" = "$NEXT_VERSION" ]; then - HIGHEST_NEXT_VERSION="$NEXT_VERSION" - fi - fi - fi - - PACKAGES_STATUS="${PACKAGES_STATUS}${sdk}:exists," - else - echo " đŸ“Ļ Package doesn't exist yet (first-time publication)" - PACKAGES_STATUS="${PACKAGES_STATUS}${sdk}:new," - fi - done - - # Determine the base version to use - if [ "$VERSION_SOURCE" = "existing" ]; then - CURRENT_VERSION="$HIGHEST_VERSION" - echo "" - echo "📊 Using highest existing version: $CURRENT_VERSION" - else - CURRENT_VERSION="0.0.0" - VERSION_SOURCE="none" - echo "" - echo "đŸ“Ļ No existing packages found, starting fresh with 0.0.0 base" - fi - - # For backward compatibility - if [ "$CURRENT_VERSION" != "0.0.0" ]; then - CURRENT_STABLE="$CURRENT_VERSION" - else - CURRENT_STABLE="" - fi - - echo "" - echo "=== PACKAGE STATUS SUMMARY ===" - echo "Base version: $CURRENT_VERSION" - echo "Highest next version: $HIGHEST_NEXT_VERSION" - echo "Version source: $VERSION_SOURCE" - echo "===============================" - - echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT - echo "version_source=$VERSION_SOURCE" >> $GITHUB_OUTPUT - echo "current_stable=$CURRENT_STABLE" >> $GITHUB_OUTPUT - echo "current_beta=" >> $GITHUB_OUTPUT - echo "current_next=$HIGHEST_NEXT_VERSION" >> $GITHUB_OUTPUT - echo "::endgroup::" - shell: bash - - - name: 'Validate custom version' - if: ${{ inputs.version-type == 'custom' }} env: + VERSION_TYPE: ${{ inputs.version-type }} CUSTOM_VERSION: ${{ inputs.custom-version }} - CURRENT_STABLE: ${{ steps.current_version.outputs.current_stable }} - CURRENT_BETA: ${{ steps.current_version.outputs.current_beta }} - CURRENT_NEXT: ${{ steps.current_version.outputs.current_next }} + RUN_NUMBER: ${{ github.run_number }} run: | - echo "::group::Validate custom version" - - if [ -z "$CUSTOM_VERSION" ]; then - echo "::error::Custom version cannot be empty when version-type is 'custom'" - echo "Please provide a valid semantic version (e.g., 1.3.4, 2.0.0, 1.2.1)" - exit 1 - fi - - # Validate semantic version format (major.minor.patch) - if [[ ! "$CUSTOM_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "::error::Invalid custom version format: '$CUSTOM_VERSION'" - echo "Version must follow semantic versioning format: major.minor.patch (e.g., 1.3.4)" - echo "Examples of valid versions: 1.0.0, 2.1.3, 10.15.7" - exit 1 - fi - - # Check if custom version already exists in NPM - echo "Checking if version $CUSTOM_VERSION already exists in NPM..." - - # Compare against current stable version - if [ -n "$CURRENT_STABLE" ] && [ "$CURRENT_STABLE" != "null" ] && [ "$CURRENT_STABLE" = "$CUSTOM_VERSION" ]; then - echo "::error::Custom version $CUSTOM_VERSION already exists as the current stable (latest) version" - echo "Please choose a different version number that hasn't been published yet" - echo "Current stable version: $CURRENT_STABLE" - exit 1 - fi - - # Compare against current beta version - if [ -n "$CURRENT_BETA" ] && [ "$CURRENT_BETA" != "null" ] && [ "$CURRENT_BETA" = "$CUSTOM_VERSION" ]; then - echo "::error::Custom version $CUSTOM_VERSION already exists as the current beta version" - echo "Please choose a different version number that hasn't been published yet" - echo "Current beta version: $CURRENT_BETA" + echo "::group::Set versions" + + BASE_VERSION=$(cat VERSION | tr -d '[:space:]') + echo "Base version from VERSION file: $BASE_VERSION" + + if [[ ! "$BASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Invalid version in VERSION file: '$BASE_VERSION'. Must be semver (e.g. 1.2.6)" exit 1 fi - - # Compare against current next version (extract base version) - if [ -n "$CURRENT_NEXT" ] && [ "$CURRENT_NEXT" != "null" ]; then - CURRENT_NEXT_BASE=$(echo "$CURRENT_NEXT" | sed 's/-next\.[0-9]*$//') - if [ "$CURRENT_NEXT_BASE" = "$CUSTOM_VERSION" ]; then - echo "::error::Custom version $CUSTOM_VERSION already exists as the base version for current next tag" - echo "Please choose a different version number that hasn't been published yet" - echo "Current next version: $CURRENT_NEXT (base: $CURRENT_NEXT_BASE)" - exit 1 - fi - fi - - # Additional check: Query NPM directly to see if this exact version exists in any existing package - echo "Performing direct NPM registry check for version $CUSTOM_VERSION..." - - # Get SDK packages dynamically and check if any existing package has this version - cd ${{ github.workspace }}/core-web/libs/sdk/ - sdk_packages=($(find . -maxdepth 1 -type d -exec basename {} \; | grep -v "^\.$")) - - for sdk in "${sdk_packages[@]}"; do - if npm view @dotcms/${sdk} >/dev/null 2>&1; then - # Package exists, check if this version exists - if npm view @dotcms/${sdk}@$CUSTOM_VERSION version >/dev/null 2>&1; then - echo "::error::Custom version $CUSTOM_VERSION already exists in NPM registry for @dotcms/${sdk}" - echo "Please choose a different version number that hasn't been published yet" - echo "You can check existing versions with: npm view @dotcms/${sdk} versions --json" - exit 1 - fi - fi - done - - cd - >/dev/null - - echo "✅ Custom version '$CUSTOM_VERSION' is valid and unique" - echo "✅ Semantic version format check: PASSED" - echo "✅ NPM registry uniqueness check: PASSED" - echo "::endgroup::" - shell: bash - - name: 'Calculate next version' - id: next_version - env: - CURRENT_VERSION: ${{ steps.current_version.outputs.current_version }} - VERSION_SOURCE: ${{ steps.current_version.outputs.version_source }} - CURRENT_STABLE: ${{ steps.current_version.outputs.current_stable }} - CURRENT_NEXT: ${{ steps.current_version.outputs.current_next }} - VERSION_TYPE: ${{ inputs.version-type }} - CUSTOM_VERSION: ${{ inputs.custom-version }} - run: | - echo "::group::Calculate next version" - - echo "Current version: $CURRENT_VERSION" - echo "Version source: $VERSION_SOURCE" - echo "Current next: $CURRENT_NEXT" - echo "Requested version type: $VERSION_TYPE" + # Calculate latest version if [ "$VERSION_TYPE" = "custom" ]; then - echo "Custom version requested: $CUSTOM_VERSION" - fi - echo "" - - # Function to check if version contains alpha or beta - is_prerelease_version() { - [[ "$1" == *"alpha"* ]] || [[ "$1" == *"beta"* ]] - } - - # Function to get next patch number for "next" tag - get_next_patch_number() { - local base_version="$1" - local current_next="$2" - - if [ -z "$current_next" ] || [ "$current_next" = "null" ]; then - echo "1" - return + if [ -z "$CUSTOM_VERSION" ]; then + echo "::error::custom-version must be set when version-type is 'custom'" + exit 1 fi - - # Extract the base version from current next (remove -next.X) - local current_base=$(echo "$current_next" | sed 's/-next\.[0-9]*$//') - - if [ "$current_base" = "$base_version" ]; then - # Same base version, increment the patch number - local current_patch=$(echo "$current_next" | sed 's/.*-next\.//') - # Validate that current_patch is numeric to prevent arithmetic errors - if [[ "$current_patch" =~ ^[0-9]+$ ]]; then - echo "$((current_patch + 1))" - else - # If patch number is not numeric (malformed), treat as different base version - echo "1" - fi - else - # Different base version, start from 1 - echo "1" + if [[ ! "$CUSTOM_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Invalid custom version: '$CUSTOM_VERSION'" + exit 1 fi - } - - # Function to compare versions (returns 0 if v1 >= v2, 1 if v1 < v2) - version_compare() { - local v1="$1" - local v2="$2" - - IFS='.' read -ra V1_PARTS <<< "$v1" - IFS='.' read -ra V2_PARTS <<< "$v2" - - for i in 0 1 2; do - local p1=${V1_PARTS[i]:-0} - local p2=${V2_PARTS[i]:-0} - - if [ "$p1" -gt "$p2" ]; then - return 0 # v1 > v2 - elif [ "$p1" -lt "$p2" ]; then - return 1 # v1 < v2 - fi - done - - return 0 # v1 == v2 - } - - # Calculate LATEST version - if [ "$VERSION_TYPE" = "custom" ]; then - # Custom version specified - NEXT_VERSION="$CUSTOM_VERSION" + LATEST_VERSION="$CUSTOM_VERSION" VERSION_TYPE_USED="custom" - - # Check if custom version is valid relative to current version - if [ "$VERSION_SOURCE" = "stable" ] && [ -n "$CURRENT_STABLE" ]; then - if version_compare "$CURRENT_STABLE" "$CUSTOM_VERSION"; then - echo "::warning::Custom version $CUSTOM_VERSION is not greater than current stable version $CURRENT_STABLE" - echo "This will still be published, but consider if this is intentional." - fi - fi - - echo "Using custom version: $CUSTOM_VERSION" - - elif [ "$VERSION_SOURCE" = "none" ] || [ "$CURRENT_VERSION" = "0.0.0" ]; then - # No version exists, start with 1.0.0 - NEXT_VERSION="1.0.0" - VERSION_TYPE_USED="initial" - echo "No existing version found, setting initial version to 1.0.0" - - elif is_prerelease_version "$CURRENT_VERSION"; then - # Current version is alpha or beta, transition to 1.0.0 stable - NEXT_VERSION="1.0.0" - VERSION_TYPE_USED="prerelease-to-stable" - echo "Transitioning from prerelease version ($CURRENT_VERSION) to stable 1.0.0" - - elif [ "$VERSION_SOURCE" = "existing" ] && [ -n "$CURRENT_STABLE" ]; then - # We have a stable version, apply versioning logic - IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_STABLE" - MAJOR=${VERSION_PARTS[0]:-1} - MINOR=${VERSION_PARTS[1]:-0} - PATCH=${VERSION_PARTS[2]:-0} - + elif [ "$VERSION_TYPE" = "auto" ]; then + LATEST_VERSION="$BASE_VERSION" + VERSION_TYPE_USED="auto-no-increment" + else + IFS='.' read -ra PARTS <<< "$BASE_VERSION" + MAJOR=${PARTS[0]}; MINOR=${PARTS[1]}; PATCH=${PARTS[2]} case "$VERSION_TYPE" in - "major") - MAJOR=$((MAJOR + 1)) - MINOR=0 - PATCH=0 - VERSION_TYPE_USED="major" - echo "Manual major version increment requested" - ;; - "minor") - MINOR=$((MINOR + 1)) - PATCH=0 - VERSION_TYPE_USED="minor" - echo "Manual minor version increment requested" - ;; - "patch") - PATCH=$((PATCH + 1)) - VERSION_TYPE_USED="patch" - echo "Manual patch version increment requested" - ;; - "auto"|*) - # Auto mode: keep current version (no increment) - VERSION_TYPE_USED="auto-no-increment" - echo "Auto mode: keeping current stable version (no increment)" - ;; + major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0; VERSION_TYPE_USED="major" ;; + minor) MINOR=$((MINOR + 1)); PATCH=0; VERSION_TYPE_USED="minor" ;; + patch) PATCH=$((PATCH + 1)); VERSION_TYPE_USED="patch" ;; + *) VERSION_TYPE_USED="auto-no-increment" ;; esac - - NEXT_VERSION="${MAJOR}.${MINOR}.${PATCH}" - else - # Fallback case - NEXT_VERSION="1.0.0" - VERSION_TYPE_USED="fallback" - echo "Fallback: setting version to 1.0.0" + LATEST_VERSION="${MAJOR}.${MINOR}.${PATCH}" fi - # Calculate NEXT version (always generated) + # next tag always uses run number — guaranteed unique + NEXT_VERSION="${LATEST_VERSION}-next.${RUN_NUMBER}" + + # Only publish latest when version actually changes if [ "$VERSION_TYPE_USED" = "auto-no-increment" ]; then - # For auto mode, use current stable version as base for next - NEXT_BASE_VERSION="$CURRENT_STABLE" + SHOULD_PUBLISH_LATEST="false" else - # Use the calculated next version as base - NEXT_BASE_VERSION="$NEXT_VERSION" + SHOULD_PUBLISH_LATEST="true" fi - - NEXT_PATCH_NUMBER=$(get_next_patch_number "$NEXT_BASE_VERSION" "$CURRENT_NEXT") - NEXT_VERSION_NEXT="${NEXT_BASE_VERSION}-next.${NEXT_PATCH_NUMBER}" echo "" - echo "=== VERSION CALCULATION RESULT ===" - echo "Previous version: $CURRENT_VERSION" - echo "Next version (latest): $NEXT_VERSION" - echo "Next version (next): $NEXT_VERSION_NEXT" - echo "Version type used: $VERSION_TYPE_USED" - echo "==================================" - - echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT - echo "next_version_next=$NEXT_VERSION_NEXT" >> $GITHUB_OUTPUT - echo "version_type_used=$VERSION_TYPE_USED" >> $GITHUB_OUTPUT - echo "::endgroup::" - shell: bash + echo "=== VERSION SUMMARY ===" + echo "Base (VERSION file): $BASE_VERSION" + echo "Latest: $LATEST_VERSION (publish: $SHOULD_PUBLISH_LATEST)" + echo "Next: $NEXT_VERSION" + echo "Version type used: $VERSION_TYPE_USED" + echo "========================" - - name: 'Validate version increment' - id: validate_version - env: - CURRENT_VERSION: ${{ steps.current_version.outputs.current_version }} - NEXT_VERSION: ${{ steps.next_version.outputs.next_version }} - NEXT_VERSION_NEXT: ${{ steps.next_version.outputs.next_version_next }} - VERSION_TYPE_USED: ${{ steps.next_version.outputs.version_type_used }} - run: | - echo "::group::Validate version increment" - echo "Validation summary:" - echo " Current: $CURRENT_VERSION" - echo " Next (latest): $NEXT_VERSION" - echo " Next (next): $NEXT_VERSION_NEXT" - echo " Type: $VERSION_TYPE_USED" - - # Basic validation - ensure we have valid semver - if [[ ! "$NEXT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "::error::Invalid version format for latest: $NEXT_VERSION" - exit 1 - fi - - if [[ ! "$NEXT_VERSION_NEXT" =~ ^[0-9]+\.[0-9]+\.[0-9]+-next\.[0-9]+$ ]]; then - echo "::error::Invalid version format for next: $NEXT_VERSION_NEXT" - exit 1 - fi - - # Determine what should be published - if [ "$CURRENT_VERSION" = "$NEXT_VERSION" ] && [ "$VERSION_TYPE_USED" = "auto-no-increment" ]; then - echo "đŸšĢ No version change detected for latest tag (${CURRENT_VERSION} → ${NEXT_VERSION})" - echo " Skipping latest publishing since version-type is 'auto' and no increment is needed." - SHOULD_PUBLISH_LATEST="false" - else - echo "✅ Version will be updated for latest tag (${CURRENT_VERSION} → ${NEXT_VERSION})" - SHOULD_PUBLISH_LATEST="true" - fi - - # Always publish to next tag - SHOULD_PUBLISH_NEXT="true" - echo "✅ Version will be published to next tag: ${NEXT_VERSION_NEXT}" - + echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT + echo "next_version_next=$NEXT_VERSION" >> $GITHUB_OUTPUT echo "should_publish_latest=$SHOULD_PUBLISH_LATEST" >> $GITHUB_OUTPUT - echo "should_publish_next=$SHOULD_PUBLISH_NEXT" >> $GITHUB_OUTPUT - - echo "✅ Version validation passed" - echo "::endgroup::" - shell: bash - - - name: 'Printing versions' - working-directory: ${{ github.workspace }}/core-web/libs/sdk/ - env: - NEXT_VERSION: ${{ steps.next_version.outputs.next_version }} - NEXT_VERSION_NEXT: ${{ steps.next_version.outputs.next_version_next }} - CURRENT_VERSION: ${{ steps.current_version.outputs.current_version }} - VERSION_TYPE_USED: ${{ steps.next_version.outputs.version_type_used }} - SHOULD_PUBLISH_LATEST: ${{ steps.validate_version.outputs.should_publish_latest }} - SHOULD_PUBLISH_NEXT: ${{ steps.validate_version.outputs.should_publish_next }} - run: | - echo "::group::Version update summary" - echo "Current version: $CURRENT_VERSION" - echo "Next version (latest): $NEXT_VERSION (publish: $SHOULD_PUBLISH_LATEST)" - echo "Next version (next): $NEXT_VERSION_NEXT (publish: $SHOULD_PUBLISH_NEXT)" - echo "Update type: $VERSION_TYPE_USED" + echo "version_type_used=$VERSION_TYPE_USED" >> $GITHUB_OUTPUT echo "::endgroup::" shell: bash - - name: 'Bump SDK version and update dependencies' + - name: 'Update package.json versions' working-directory: ${{ github.workspace }}/core-web/libs/sdk/ env: - NEXT_VERSION: ${{ steps.next_version.outputs.next_version }} - NEXT_VERSION_NEXT: ${{ steps.next_version.outputs.next_version_next }} + LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} EXAMPLES_PATH: ${{ github.workspace }}/examples - SHOULD_PUBLISH_LATEST: ${{ steps.validate_version.outputs.should_publish_latest }} run: | - echo "Preparing versions:" - echo " Latest: $NEXT_VERSION (will publish: $SHOULD_PUBLISH_LATEST)" - echo " Next: $NEXT_VERSION_NEXT (will publish: $SHOULD_PUBLISH_NEXT)" + echo "::group::Update package.json versions" - # Function to update the version in package.json using jq - update_version() { - local pkg_dir="$1" - local new_version="$2" - local package_json_path="$pkg_dir/package.json" - - if [ -f "$package_json_path" ]; then - jq --arg new_version "$new_version" '.version = $new_version' "$package_json_path" > tmp.$$.json && mv tmp.$$.json "$package_json_path" - echo "✅ Updated version in $package_json_path to $new_version" - else - echo "::warning::No package.json found in $pkg_dir" - fi - } + sdk_packages=($(find . -maxdepth 1 -mindepth 1 -type d -exec basename {} \;)) + echo "Found SDK packages: ${sdk_packages[*]}" - # Function to update peerDependencies in package.json - update_peer_dependencies() { - local pkg_dir="$1" - local new_version="$2" - local package_json_path="$pkg_dir/package.json" + for sdk in "${sdk_packages[@]}"; do + pkg="$sdk/package.json" + if [ -f "$pkg" ]; then + jq --arg v "$LATEST_VERSION" '.version = $v' "$pkg" > tmp.$$.json && mv tmp.$$.json "$pkg" + echo " ✅ $sdk -> $LATEST_VERSION" - if [ -f "$package_json_path" ]; then + # Update peerDependencies that reference other SDK packages for dep in "${sdk_packages[@]}"; do - if jq -e ".peerDependencies[\"@dotcms/$dep\"]" "$package_json_path" >/dev/null; then - jq --arg new_version "^$new_version" ".peerDependencies[\"@dotcms/$dep\"] = \$new_version" "$package_json_path" > tmp.$$.json && mv tmp.$$.json "$package_json_path" - echo " â†ŗ Updated peerDependency @dotcms/$dep to ^$new_version" + if jq -e ".peerDependencies[\"@dotcms/$dep\"]" "$pkg" >/dev/null 2>&1; then + jq --arg dep "@dotcms/$dep" --arg v "^$LATEST_VERSION" \ + '.peerDependencies[$dep] = $v' "$pkg" > tmp.$$.json && mv tmp.$$.json "$pkg" + echo " â†ŗ peerDependency @dotcms/$dep -> ^$LATEST_VERSION" fi done fi - } - - # Function to update dependencies in examples package.json - update_dependencies_in_examples() { - local example_dir="$1" - local new_version="$2" - local package_json_path="$example_dir/package.json" + done - if [ -f "$package_json_path" ]; then - local updated=false + # Update example projects + if [ -d "$EXAMPLES_PATH" ]; then + while IFS= read -r pkg_json; do for dep in "${sdk_packages[@]}"; do - if jq -e ".dependencies[\"@dotcms/$dep\"]" "$package_json_path" >/dev/null; then - jq --arg sdk_name "@dotcms/$dep" --arg new_version "^$new_version" \ - '.dependencies[$sdk_name] = $new_version' \ - "$package_json_path" > tmp.$$.json && mv tmp.$$.json "$package_json_path" - updated=true + if jq -e ".dependencies[\"@dotcms/$dep\"]" "$pkg_json" >/dev/null 2>&1; then + jq --arg dep "@dotcms/$dep" --arg v "^$LATEST_VERSION" \ + '.dependencies[$dep] = $v' "$pkg_json" > tmp.$$.json && mv tmp.$$.json "$pkg_json" fi done - if [ "$updated" = true ]; then - echo "✅ Updated dependencies in $package_json_path" - fi - fi - } - - # Detect all SDK packages dynamically in the libs/sdk directory - sdk_packages=($(find . -maxdepth 1 -type d -exec basename {} \; | grep -v "^\.$")) - - echo "Found SDK packages: ${sdk_packages[*]}" - echo "" - - # We'll use the latest version for package.json updates (even if not publishing to latest) - # This ensures consistency in the build artifacts - VERSION_FOR_PACKAGES="$NEXT_VERSION" - - # Step 1: Update the version in each SDK package - echo "đŸ“Ļ Updating SDK package versions to $VERSION_FOR_PACKAGES..." - for sdk in "${sdk_packages[@]}"; do - update_version "$sdk" "$VERSION_FOR_PACKAGES" - done - echo "" - - # Step 2: Update peerDependencies in each SDK package - echo "🔗 Updating SDK peer dependencies..." - for sdk in "${sdk_packages[@]}"; do - update_peer_dependencies "$sdk" "$VERSION_FOR_PACKAGES" - done - echo "" - - # Step 3: Update dependencies in example projects - echo "📚 Updating example project dependencies..." - example_packages=$(find $EXAMPLES_PATH -name "package.json" -not -path "*/node_modules/*" 2>/dev/null || echo "") - - if [ -n "$example_packages" ]; then - for package_json_path in $example_packages; do - example_dir=$(dirname "$package_json_path") - update_dependencies_in_examples "$example_dir" "$VERSION_FOR_PACKAGES" - done - else - echo "No example packages found" + done < <(find "$EXAMPLES_PATH" -name "package.json" -not -path "*/node_modules/*") fi - echo "" - echo "✅ All version updates completed successfully" - shell: bash - - name: 'Printing SDK packages configuration' - env: - SDK_LIBS_PATH: ${{ github.workspace }}/core-web/libs/sdk - EXAMPLES_PATH: ${{ github.workspace }}/examples - run: | - print_packages() { - cd $1 - ls -ls | awk '{ print$10 }' | grep -v '^$' | while read a; do - if [ -f "./${a}/package.json" ]; then - echo -e "${a}:" - cat "./${a}/package.json" | jq '.name, .version' - echo "" - fi - done - } - echo "::group::SDK and Example packages configuration" - echo "SDK libs:" - print_packages "$SDK_LIBS_PATH" - echo "" - if [ -d "$EXAMPLES_PATH" ]; then - echo "Examples:" - print_packages "$EXAMPLES_PATH" - fi echo "::endgroup::" shell: bash @@ -630,7 +198,6 @@ runs: yarn install npm --version node --version - npx --version shell: bash - name: 'Build SDK packages' @@ -639,84 +206,65 @@ runs: npx nx run-many --target=build --projects='sdk-*' --configuration=production --skip-nx-cache shell: bash - - name: 'Publishing sdk into NPM registry' + - name: 'Publish SDK packages to NPM' id: publish_packages working-directory: ${{ github.workspace }}/core-web/dist/libs/sdk/ env: - NEXT_VERSION: ${{ steps.next_version.outputs.next_version }} - NEXT_VERSION_NEXT: ${{ steps.next_version.outputs.next_version_next }} + LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} + NEXT_VERSION: ${{ steps.set_versions.outputs.next_version_next }} NPM_AUTH_TOKEN: ${{ inputs.npm-token }} NPM_TAG_LATEST: ${{ inputs.npm-package-tag }} - VERSION_TYPE_USED: ${{ steps.next_version.outputs.version_type_used }} - SHOULD_PUBLISH_LATEST: ${{ steps.validate_version.outputs.should_publish_latest }} - SHOULD_PUBLISH_NEXT: ${{ steps.validate_version.outputs.should_publish_next }} + SHOULD_PUBLISH_LATEST: ${{ steps.set_versions.outputs.should_publish_latest }} run: | echo "::group::Publishing SDK packages" - echo "Publishing plan:" - echo " Latest tag ($NPM_TAG_LATEST): $NEXT_VERSION (publish: $SHOULD_PUBLISH_LATEST)" - echo " Next tag: $NEXT_VERSION_NEXT (publish: $SHOULD_PUBLISH_NEXT)" - echo " Version type: $VERSION_TYPE_USED" + echo "Latest: $LATEST_VERSION (publish: $SHOULD_PUBLISH_LATEST)" + echo "Next: $NEXT_VERSION" echo "" - - # Set up NPM authentication + echo "//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}" > ~/.npmrc - - sdks=$(ls) + PUBLISH_LATEST_SUCCESS=true PUBLISH_NEXT_SUCCESS=true - - for sdk in $sdks; do + + for sdk in $(ls); do echo "đŸ“Ļ Processing @dotcms/${sdk}..." - cd $sdk && echo " Working directory: $(pwd)" - - # Save original version before any modifications + cd "$sdk" + ORIGINAL_VERSION=$(jq -r '.version' package.json) - - # Publish to latest tag if needed + if [ "$SHOULD_PUBLISH_LATEST" = "true" ]; then - echo " 🚀 Publishing to latest tag: @dotcms/${sdk}@${NEXT_VERSION}" - if npm publish --access public --tag $NPM_TAG_LATEST; then - echo " ✅ Successfully published to latest tag" + echo " 🚀 Publishing latest: @dotcms/${sdk}@${LATEST_VERSION}" + if npm publish --access public --tag "$NPM_TAG_LATEST"; then + echo " ✅ Published to latest" else - echo " ❌ Failed to publish to latest tag" + echo " ❌ Failed to publish to latest" PUBLISH_LATEST_SUCCESS=false fi else - echo " â­ī¸ Skipping latest tag publishing (no version change)" + echo " â­ī¸ Skipping latest (auto mode, no version change)" fi - - # Always publish to next tag - if [ "$SHOULD_PUBLISH_NEXT" = "true" ]; then - echo " 🚀 Publishing to next tag: @dotcms/${sdk}@${NEXT_VERSION_NEXT}" - - # Temporarily update package.json version for next publication - jq --arg next_version "$NEXT_VERSION_NEXT" '.version = $next_version' package.json > tmp.$$.json && mv tmp.$$.json package.json - - if npm publish --access public --tag next; then - echo " ✅ Successfully published to next tag" - else - echo " ❌ Failed to publish to next tag" - PUBLISH_NEXT_SUCCESS=false - fi - - # IMPORTANT: Revert package.json back to original stable version - jq --arg original_version "$ORIGINAL_VERSION" '.version = $original_version' package.json > tmp.$$.json && mv tmp.$$.json package.json - echo " â†Šī¸ Reverted package.json version back to $ORIGINAL_VERSION" + + echo " 🚀 Publishing next: @dotcms/${sdk}@${NEXT_VERSION}" + jq --arg v "$NEXT_VERSION" '.version = $v' package.json > tmp.$$.json && mv tmp.$$.json package.json + if npm publish --access public --tag next; then + echo " ✅ Published to next" + else + echo " ❌ Failed to publish to next" + PUBLISH_NEXT_SUCCESS=false fi - + jq --arg v "$ORIGINAL_VERSION" '.version = $v' package.json > tmp.$$.json && mv tmp.$$.json package.json + cd .. echo "" done - - # Final status + if [ "$PUBLISH_LATEST_SUCCESS" = "true" ] && [ "$PUBLISH_NEXT_SUCCESS" = "true" ]; then echo "🎉 All SDK packages published successfully!" else echo "❌ Some publications failed" exit 1 fi - - # At the end of the publishing step, set the actual results + echo "actual_published_latest=$PUBLISH_LATEST_SUCCESS" >> $GITHUB_OUTPUT echo "actual_published_next=$PUBLISH_NEXT_SUCCESS" >> $GITHUB_OUTPUT echo "::endgroup::" @@ -728,38 +276,27 @@ runs: env: ACTUAL_PUBLISHED_LATEST: ${{ steps.publish_packages.outputs.actual_published_latest }} ACTUAL_PUBLISHED_NEXT: ${{ steps.publish_packages.outputs.actual_published_next }} - NEXT_VERSION: ${{ steps.next_version.outputs.next_version }} - NEXT_VERSION_NEXT: ${{ steps.next_version.outputs.next_version_next }} + LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} + NEXT_VERSION: ${{ steps.set_versions.outputs.next_version_next }} run: | echo "published_latest=$ACTUAL_PUBLISHED_LATEST" >> $GITHUB_OUTPUT echo "published_next=$ACTUAL_PUBLISHED_NEXT" >> $GITHUB_OUTPUT - - # Backward compatibility: published is true if either latest or next was published + if [ "$ACTUAL_PUBLISHED_LATEST" = "true" ] || [ "$ACTUAL_PUBLISHED_NEXT" = "true" ]; then PUBLISHED="true" else PUBLISHED="false" fi echo "published=$PUBLISHED" >> $GITHUB_OUTPUT - - # Create npm-package-version output with clean formatting - # Template expects: [ `${{ steps.deployment_status.outputs.npm_package_version }}` ] + if [ "$ACTUAL_PUBLISHED_LATEST" = "true" ] && [ "$ACTUAL_PUBLISHED_NEXT" = "true" ]; then - # Both published - clean dual format - NPM_PACKAGE_VERSION="${NEXT_VERSION} (latest) and ${NEXT_VERSION_NEXT} (next)" + NPM_PACKAGE_VERSION="${LATEST_VERSION} (latest) and ${NEXT_VERSION} (next)" elif [ "$ACTUAL_PUBLISHED_LATEST" = "true" ]; then - # Only latest published - NPM_PACKAGE_VERSION="${NEXT_VERSION} (latest)" + NPM_PACKAGE_VERSION="${LATEST_VERSION} (latest)" elif [ "$ACTUAL_PUBLISHED_NEXT" = "true" ]; then - # Only next published - NPM_PACKAGE_VERSION="${NEXT_VERSION_NEXT} (next)" + NPM_PACKAGE_VERSION="${NEXT_VERSION} (next)" else - # Nothing published NPM_PACKAGE_VERSION="No versions published" fi echo "npm_package_version=$NPM_PACKAGE_VERSION" >> $GITHUB_OUTPUT - - echo "✅ Outputs set:" - echo " published: $PUBLISHED" - echo " npm_package_version: $NPM_PACKAGE_VERSION" shell: bash diff --git a/.github/workflows/cicd_manual-release-sdks.yml b/.github/workflows/cicd_manual-release-sdks.yml index 99be24649aa9..589997229646 100644 --- a/.github/workflows/cicd_manual-release-sdks.yml +++ b/.github/workflows/cicd_manual-release-sdks.yml @@ -28,7 +28,7 @@ jobs: release-sdks: name: 'Release SDK Packages' runs-on: ubuntu-latest - + steps: - name: 'Checkout repository' uses: actions/checkout@v4 @@ -42,26 +42,53 @@ jobs: echo "Version type: ${{ inputs.version-type }}" echo "Custom version: ${{ inputs.custom-version }}" echo "Branch: ${{ inputs.ref }}" - - # Validate that custom-version is provided when version-type is custom + if [ "${{ inputs.version-type }}" = "custom" ]; then if [ -z "${{ inputs.custom-version }}" ]; then - echo "::error::Custom version must be provided when version-type is 'custom'" - echo "Please provide a valid semantic version (e.g., 1.3.4, 2.0.0, 1.2.1)" + echo "::error::custom-version must be provided when version-type is 'custom'" exit 1 fi - - # Basic semver validation if [[ ! "${{ inputs.custom-version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "::error::Invalid custom version format: '${{ inputs.custom-version }}'" - echo "Version must follow semantic versioning format: major.minor.patch (e.g., 1.3.4)" exit 1 fi - echo "✅ Custom version '${{ inputs.custom-version }}' is valid" fi echo "::endgroup::" + - name: 'Bump VERSION file' + id: bump_version + run: | + echo "::group::Bump VERSION file" + CURRENT=$(cat core-web/libs/sdk/VERSION | tr -d '[:space:]') + echo "Current version: $CURRENT" + + IFS='.' read -ra PARTS <<< "$CURRENT" + MAJOR=${PARTS[0]}; MINOR=${PARTS[1]}; PATCH=${PARTS[2]} + + case "${{ inputs.version-type }}" in + major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;; + minor) MINOR=$((MINOR + 1)); PATCH=0 ;; + patch) PATCH=$((PATCH + 1)) ;; + custom) MAJOR=0; MINOR=0; PATCH=0 + IFS='.' read -ra CPARTS <<< "${{ inputs.custom-version }}" + MAJOR=${CPARTS[0]}; MINOR=${CPARTS[1]}; PATCH=${CPARTS[2]} ;; + esac + + NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" + echo "$NEW_VERSION" > core-web/libs/sdk/VERSION + echo "New version: $NEW_VERSION" + echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT + echo "::endgroup::" + + - name: 'Commit and push VERSION bump' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add core-web/libs/sdk/VERSION + git commit -m "chore(sdk): bump SDK version to ${{ steps.bump_version.outputs.new_version }}" + git push + - name: 'Deploy JavaScript SDK' id: deploy-javascript-sdk uses: ./.github/actions/core-cicd/deployment/deploy-javascript-sdk diff --git a/core-web/libs/sdk/VERSION b/core-web/libs/sdk/VERSION new file mode 100644 index 000000000000..3c43790f5d82 --- /dev/null +++ b/core-web/libs/sdk/VERSION @@ -0,0 +1 @@ +1.2.6 From fcbbd58463cdedcfd231d43c4e5eb70026bab038 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Thu, 16 Apr 2026 15:58:29 -0600 Subject: [PATCH 2/8] fix(sdk): address PR review comments on SDK versioning workflow - Add VERSION file existence check with clear error message - Fix run_number collision: use run_id-run_attempt (globally unique) - Fix double-bump bug: remove pre-bump steps from manual workflow; action now owns the single VERSION increment and git commit/push - Add custom-version same-as-current guard to prevent no-op commits - Add permissions: contents: write to manual release job - Fix for sdk in $(ls) fragility: use find -type d instead Co-Authored-By: Claude Sonnet 4.6 --- .../deploy-javascript-sdk/action.yml | 29 +++++++++++++-- .../workflows/cicd_manual-release-sdks.yml | 35 ++----------------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml index 5451c4debc4d..f839eb33e37d 100644 --- a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml +++ b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml @@ -3,7 +3,7 @@ # VERSIONING: # - Single source of truth: core-web/libs/sdk/VERSION file # - LATEST TAG: published only when version-type != 'auto' (manual releases) -# - NEXT TAG: always published on trunk runs, suffix = GITHUB_RUN_NUMBER (unique, no collision) +# - NEXT TAG: always published on trunk runs, suffix = run_id-run_attempt (globally unique, no collision) # name: 'SDK Publish NPM Packages - Stable' description: 'Publish stable versions of the dotCMS SDK libs on NPM registry.' @@ -85,10 +85,15 @@ runs: env: VERSION_TYPE: ${{ inputs.version-type }} CUSTOM_VERSION: ${{ inputs.custom-version }} - RUN_NUMBER: ${{ github.run_number }} + RUN_NUMBER: ${{ github.run_id }}-${{ github.run_attempt }} run: | echo "::group::Set versions" + if [ ! -f "VERSION" ]; then + echo "::error::VERSION file not found at core-web/libs/sdk/VERSION" + exit 1 + fi + BASE_VERSION=$(cat VERSION | tr -d '[:space:]') echo "Base version from VERSION file: $BASE_VERSION" @@ -107,6 +112,10 @@ runs: echo "::error::Invalid custom version: '$CUSTOM_VERSION'" exit 1 fi + if [ "$CUSTOM_VERSION" = "$BASE_VERSION" ]; then + echo "::error::Requested SDK version '$CUSTOM_VERSION' matches the current version. Please choose a different version." + exit 1 + fi LATEST_VERSION="$CUSTOM_VERSION" VERSION_TYPE_USED="custom" elif [ "$VERSION_TYPE" = "auto" ]; then @@ -149,6 +158,20 @@ runs: echo "::endgroup::" shell: bash + - name: 'Commit and push VERSION bump' + if: ${{ steps.set_versions.outputs.should_publish_latest == 'true' }} + working-directory: ${{ github.workspace }}/core-web/libs/sdk/ + env: + LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} + run: | + echo "$LATEST_VERSION" > VERSION + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add VERSION + git commit -m "chore(sdk): bump SDK version to $LATEST_VERSION" + git push + shell: bash + - name: 'Update package.json versions' working-directory: ${{ github.workspace }}/core-web/libs/sdk/ env: @@ -226,7 +249,7 @@ runs: PUBLISH_LATEST_SUCCESS=true PUBLISH_NEXT_SUCCESS=true - for sdk in $(ls); do + for sdk in $(find . -maxdepth 1 -mindepth 1 -type d -exec basename {} \;); do echo "đŸ“Ļ Processing @dotcms/${sdk}..." cd "$sdk" diff --git a/.github/workflows/cicd_manual-release-sdks.yml b/.github/workflows/cicd_manual-release-sdks.yml index 589997229646..af8f37239ab2 100644 --- a/.github/workflows/cicd_manual-release-sdks.yml +++ b/.github/workflows/cicd_manual-release-sdks.yml @@ -28,6 +28,8 @@ jobs: release-sdks: name: 'Release SDK Packages' runs-on: ubuntu-latest + permissions: + contents: write steps: - name: 'Checkout repository' @@ -56,39 +58,6 @@ jobs: fi echo "::endgroup::" - - name: 'Bump VERSION file' - id: bump_version - run: | - echo "::group::Bump VERSION file" - CURRENT=$(cat core-web/libs/sdk/VERSION | tr -d '[:space:]') - echo "Current version: $CURRENT" - - IFS='.' read -ra PARTS <<< "$CURRENT" - MAJOR=${PARTS[0]}; MINOR=${PARTS[1]}; PATCH=${PARTS[2]} - - case "${{ inputs.version-type }}" in - major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;; - minor) MINOR=$((MINOR + 1)); PATCH=0 ;; - patch) PATCH=$((PATCH + 1)) ;; - custom) MAJOR=0; MINOR=0; PATCH=0 - IFS='.' read -ra CPARTS <<< "${{ inputs.custom-version }}" - MAJOR=${CPARTS[0]}; MINOR=${CPARTS[1]}; PATCH=${CPARTS[2]} ;; - esac - - NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" - echo "$NEW_VERSION" > core-web/libs/sdk/VERSION - echo "New version: $NEW_VERSION" - echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "::endgroup::" - - - name: 'Commit and push VERSION bump' - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add core-web/libs/sdk/VERSION - git commit -m "chore(sdk): bump SDK version to ${{ steps.bump_version.outputs.new_version }}" - git push - - name: 'Deploy JavaScript SDK' id: deploy-javascript-sdk uses: ./.github/actions/core-cicd/deployment/deploy-javascript-sdk From dba31323ea3bf3bc43c2ce3e7b90f22480f238f3 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Thu, 16 Apr 2026 16:08:02 -0600 Subject: [PATCH 3/8] fix(sdk): replace Maven/Node setup with actions/setup-node Maven was only used to install the Node/yarn toolchain. Replacing with actions/setup-node is faster and removes the Java dependency entirely. Co-Authored-By: Claude Sonnet 4.6 --- .../deploy-javascript-sdk/action.yml | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml index f839eb33e37d..970859253ce2 100644 --- a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml +++ b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml @@ -58,26 +58,10 @@ runs: ref: ${{ inputs.ref }} token: ${{ inputs.github-token }} - - name: 'Run Maven Job' - uses: ./.github/actions/core-cicd/maven-job + - name: 'Setup Node' + uses: actions/setup-node@v4 with: - stage-name: 'Build' - maven-args: 'process-resources -pl :dotcms-core-web -am' - requires-node: true - cleanup-runner: true - generate-docker: false - generate-artifacts: false - version: '1.0.0-SNAPSHOT' - github-token: ${{ inputs.github-token }} - - - name: 'Adding node and yarn to the PATH env' - run: | - echo "::group::Adding node and yarn to the PATH env" - BASE_PATH=${{ github.workspace }}/installs - ls -Rla ${BASE_PATH}/node - echo "PATH=${BASE_PATH}/node:${BASE_PATH}/node/yarn/dist/bin:$PATH" >> $GITHUB_ENV - echo "::endgroup::" - shell: bash + node-version: '22.15.0' - name: 'Set versions from VERSION file' id: set_versions From 81808c805bb898464f7a56f4130732d06f3777b9 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Thu, 16 Apr 2026 17:54:36 -0600 Subject: [PATCH 4/8] fix(sdk): address Copilot review comments on deploy action - Move VERSION commit/push to after successful publish so the repo version always reflects what actually landed on NPM - Enable Corepack after setup-node to guarantee the Yarn version declared in packageManager is used, not the runner default - Fail fast with a clear error on unknown version-type instead of silently falling through to auto-no-increment Co-Authored-By: Claude Sonnet 4.6 --- .../deploy-javascript-sdk/action.yml | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml index 970859253ce2..19a8b9ca41a9 100644 --- a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml +++ b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml @@ -63,6 +63,10 @@ runs: with: node-version: '22.15.0' + - name: 'Enable Corepack' + run: corepack enable + shell: bash + - name: 'Set versions from VERSION file' id: set_versions working-directory: ${{ github.workspace }}/core-web/libs/sdk/ @@ -112,7 +116,10 @@ runs: major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0; VERSION_TYPE_USED="major" ;; minor) MINOR=$((MINOR + 1)); PATCH=0; VERSION_TYPE_USED="minor" ;; patch) PATCH=$((PATCH + 1)); VERSION_TYPE_USED="patch" ;; - *) VERSION_TYPE_USED="auto-no-increment" ;; + *) + echo "::error::Invalid version-type '$VERSION_TYPE'. Must be one of: auto, patch, minor, major, custom." + exit 1 + ;; esac LATEST_VERSION="${MAJOR}.${MINOR}.${PATCH}" fi @@ -142,20 +149,6 @@ runs: echo "::endgroup::" shell: bash - - name: 'Commit and push VERSION bump' - if: ${{ steps.set_versions.outputs.should_publish_latest == 'true' }} - working-directory: ${{ github.workspace }}/core-web/libs/sdk/ - env: - LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} - run: | - echo "$LATEST_VERSION" > VERSION - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add VERSION - git commit -m "chore(sdk): bump SDK version to $LATEST_VERSION" - git push - shell: bash - - name: 'Update package.json versions' working-directory: ${{ github.workspace }}/core-web/libs/sdk/ env: @@ -277,6 +270,20 @@ runs: echo "::endgroup::" shell: bash + - name: 'Commit and push VERSION bump' + if: ${{ steps.set_versions.outputs.should_publish_latest == 'true' && steps.publish_packages.outputs.actual_published_latest == 'true' }} + working-directory: ${{ github.workspace }}/core-web/libs/sdk/ + env: + LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} + run: | + echo "$LATEST_VERSION" > VERSION + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add VERSION + git commit -m "chore(sdk): bump SDK version to $LATEST_VERSION" + git push + shell: bash + - name: 'Set output' id: deployment_status if: success() From 6fd6250634aeff7d7a60b8cd06b84727c9151fd8 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Thu, 16 Apr 2026 18:07:14 -0600 Subject: [PATCH 5/8] fix(sdk): address second round of Copilot review comments - Use node-version-file: .nvmrc instead of hardcoded Node version - Add set -euo pipefail to bash steps that mutate package.json so any jq failure stops the action immediately instead of silently continuing - Write actual_published_latest/next outputs before exit 1 so the VERSION commit step fires correctly when latest succeeds but next fails - Update PR description to reflect that the action owns VERSION commits Co-Authored-By: Claude Sonnet 4.6 --- .../deployment/deploy-javascript-sdk/action.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml index 19a8b9ca41a9..6a649429bc75 100644 --- a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml +++ b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml @@ -61,7 +61,7 @@ runs: - name: 'Setup Node' uses: actions/setup-node@v4 with: - node-version: '22.15.0' + node-version-file: 'core-web/.nvmrc' - name: 'Enable Corepack' run: corepack enable @@ -155,6 +155,7 @@ runs: LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} EXAMPLES_PATH: ${{ github.workspace }}/examples run: | + set -euo pipefail echo "::group::Update package.json versions" sdk_packages=($(find . -maxdepth 1 -mindepth 1 -type d -exec basename {} \;)) @@ -195,6 +196,7 @@ runs: - name: 'Install project' working-directory: ${{ github.workspace }}/core-web/ run: | + set -euo pipefail yarn install npm --version node --version @@ -203,6 +205,7 @@ runs: - name: 'Build SDK packages' working-directory: ${{ github.workspace }}/core-web/ run: | + set -euo pipefail npx nx run-many --target=build --projects='sdk-*' --configuration=production --skip-nx-cache shell: bash @@ -258,15 +261,17 @@ runs: echo "" done + echo "actual_published_latest=$PUBLISH_LATEST_SUCCESS" >> $GITHUB_OUTPUT + echo "actual_published_next=$PUBLISH_NEXT_SUCCESS" >> $GITHUB_OUTPUT + if [ "$PUBLISH_LATEST_SUCCESS" = "true" ] && [ "$PUBLISH_NEXT_SUCCESS" = "true" ]; then echo "🎉 All SDK packages published successfully!" else echo "❌ Some publications failed" + echo "::endgroup::" exit 1 fi - echo "actual_published_latest=$PUBLISH_LATEST_SUCCESS" >> $GITHUB_OUTPUT - echo "actual_published_next=$PUBLISH_NEXT_SUCCESS" >> $GITHUB_OUTPUT echo "::endgroup::" shell: bash From cb503764b024e0d840b6985bab9e7b81baacb969 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Thu, 16 Apr 2026 18:16:26 -0600 Subject: [PATCH 6/8] refactor(sdk): align release model with dotCMS branch pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses architectural concern about VERSION file on main and merge queue disruption from direct pushes. action.yml: - Removed version increment logic and git commit/push — action is now a pure publisher, reads VERSION from whatever ref is checked out - Replaced version-type/custom-version inputs with publish-latest flag - @next always published; @latest only when publish-latest=true cicd_manual-release-sdks.yml: - Creates a release branch (sdk/release-X.Y.Z) from main - Commits VERSION bump on the release branch, never on main directly - Publishes @latest from the release branch - Opens a PR to bump VERSION to the next patch on main so trunk @next builds stay ahead of @latest semver-wise - No merge queue bypass; main only changes via normal PR flow Co-Authored-By: Claude Sonnet 4.6 --- .../deploy-javascript-sdk/action.yml | 117 ++++-------------- .../workflows/cicd_manual-release-sdks.yml | 99 ++++++++++++--- 2 files changed, 107 insertions(+), 109 deletions(-) diff --git a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml index 6a649429bc75..fe67a4647a48 100644 --- a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml +++ b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml @@ -2,8 +2,8 @@ # # VERSIONING: # - Single source of truth: core-web/libs/sdk/VERSION file -# - LATEST TAG: published only when version-type != 'auto' (manual releases) -# - NEXT TAG: always published on trunk runs, suffix = run_id-run_attempt (globally unique, no collision) +# - LATEST TAG: published by cicd_manual-release-sdks.yml from a release branch +# - NEXT TAG: always published; base version read from VERSION on the checked-out ref # name: 'SDK Publish NPM Packages - Stable' description: 'Publish stable versions of the dotCMS SDK libs on NPM registry.' @@ -16,17 +16,13 @@ inputs: description: 'NPM token' required: true npm-package-tag: - description: 'Package tag for stable releases' + description: 'Package tag (latest or next)' required: false - default: 'latest' - version-type: - description: 'Version type: auto (default), patch, minor, major, or custom. Auto means no increment — publishes next tag only.' + default: 'next' + publish-latest: + description: 'Whether to publish the @latest tag in addition to @next' required: false - default: 'auto' - custom-version: - description: 'Custom version to set (e.g., 1.3.4, 2.1.0). Only used when version-type is "custom". Must be valid semver format.' - required: false - default: '' + default: 'false' github-token: description: 'GitHub Token' required: true @@ -36,7 +32,7 @@ outputs: value: ${{ steps.deployment_status.outputs.npm_package_version }} npm-package-version-next: description: 'SDK libs - NPM package version for next tag' - value: ${{ steps.set_versions.outputs.next_version_next }} + value: ${{ steps.set_versions.outputs.next_version }} published-latest: description: 'SDK libs - Published to latest tag' value: ${{ steps.deployment_status.outputs.published_latest }} @@ -44,11 +40,8 @@ outputs: description: 'SDK libs - Published to next tag' value: ${{ steps.deployment_status.outputs.published_next }} published: - description: 'SDK libs - Published (backward compatibility - true if any tag published)' + description: 'SDK libs - Published (true if any tag published)' value: ${{ steps.deployment_status.outputs.published }} - version-type-used: - description: 'Type of version increment that was applied' - value: ${{ steps.set_versions.outputs.version_type_used }} runs: using: "composite" steps: @@ -71,10 +64,9 @@ runs: id: set_versions working-directory: ${{ github.workspace }}/core-web/libs/sdk/ env: - VERSION_TYPE: ${{ inputs.version-type }} - CUSTOM_VERSION: ${{ inputs.custom-version }} - RUN_NUMBER: ${{ github.run_id }}-${{ github.run_attempt }} + RUN_NUMBER: ${{ github.run_number }} run: | + set -euo pipefail echo "::group::Set versions" if [ ! -f "VERSION" ]; then @@ -90,62 +82,17 @@ runs: exit 1 fi - # Calculate latest version - if [ "$VERSION_TYPE" = "custom" ]; then - if [ -z "$CUSTOM_VERSION" ]; then - echo "::error::custom-version must be set when version-type is 'custom'" - exit 1 - fi - if [[ ! "$CUSTOM_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "::error::Invalid custom version: '$CUSTOM_VERSION'" - exit 1 - fi - if [ "$CUSTOM_VERSION" = "$BASE_VERSION" ]; then - echo "::error::Requested SDK version '$CUSTOM_VERSION' matches the current version. Please choose a different version." - exit 1 - fi - LATEST_VERSION="$CUSTOM_VERSION" - VERSION_TYPE_USED="custom" - elif [ "$VERSION_TYPE" = "auto" ]; then - LATEST_VERSION="$BASE_VERSION" - VERSION_TYPE_USED="auto-no-increment" - else - IFS='.' read -ra PARTS <<< "$BASE_VERSION" - MAJOR=${PARTS[0]}; MINOR=${PARTS[1]}; PATCH=${PARTS[2]} - case "$VERSION_TYPE" in - major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0; VERSION_TYPE_USED="major" ;; - minor) MINOR=$((MINOR + 1)); PATCH=0; VERSION_TYPE_USED="minor" ;; - patch) PATCH=$((PATCH + 1)); VERSION_TYPE_USED="patch" ;; - *) - echo "::error::Invalid version-type '$VERSION_TYPE'. Must be one of: auto, patch, minor, major, custom." - exit 1 - ;; - esac - LATEST_VERSION="${MAJOR}.${MINOR}.${PATCH}" - fi - - # next tag always uses run number — guaranteed unique - NEXT_VERSION="${LATEST_VERSION}-next.${RUN_NUMBER}" - - # Only publish latest when version actually changes - if [ "$VERSION_TYPE_USED" = "auto-no-increment" ]; then - SHOULD_PUBLISH_LATEST="false" - else - SHOULD_PUBLISH_LATEST="true" - fi + NEXT_VERSION="${BASE_VERSION}-next.${RUN_NUMBER}" echo "" echo "=== VERSION SUMMARY ===" echo "Base (VERSION file): $BASE_VERSION" - echo "Latest: $LATEST_VERSION (publish: $SHOULD_PUBLISH_LATEST)" + echo "Latest: $BASE_VERSION" echo "Next: $NEXT_VERSION" - echo "Version type used: $VERSION_TYPE_USED" echo "========================" - echo "latest_version=$LATEST_VERSION" >> $GITHUB_OUTPUT - echo "next_version_next=$NEXT_VERSION" >> $GITHUB_OUTPUT - echo "should_publish_latest=$SHOULD_PUBLISH_LATEST" >> $GITHUB_OUTPUT - echo "version_type_used=$VERSION_TYPE_USED" >> $GITHUB_OUTPUT + echo "latest_version=$BASE_VERSION" >> $GITHUB_OUTPUT + echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT echo "::endgroup::" shell: bash @@ -214,13 +161,12 @@ runs: working-directory: ${{ github.workspace }}/core-web/dist/libs/sdk/ env: LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} - NEXT_VERSION: ${{ steps.set_versions.outputs.next_version_next }} + NEXT_VERSION: ${{ steps.set_versions.outputs.next_version }} NPM_AUTH_TOKEN: ${{ inputs.npm-token }} - NPM_TAG_LATEST: ${{ inputs.npm-package-tag }} - SHOULD_PUBLISH_LATEST: ${{ steps.set_versions.outputs.should_publish_latest }} + PUBLISH_LATEST: ${{ inputs.publish-latest }} run: | echo "::group::Publishing SDK packages" - echo "Latest: $LATEST_VERSION (publish: $SHOULD_PUBLISH_LATEST)" + echo "Latest: $LATEST_VERSION (publish: $PUBLISH_LATEST)" echo "Next: $NEXT_VERSION" echo "" @@ -235,16 +181,14 @@ runs: ORIGINAL_VERSION=$(jq -r '.version' package.json) - if [ "$SHOULD_PUBLISH_LATEST" = "true" ]; then + if [ "$PUBLISH_LATEST" = "true" ]; then echo " 🚀 Publishing latest: @dotcms/${sdk}@${LATEST_VERSION}" - if npm publish --access public --tag "$NPM_TAG_LATEST"; then + if npm publish --access public --tag latest; then echo " ✅ Published to latest" else echo " ❌ Failed to publish to latest" PUBLISH_LATEST_SUCCESS=false fi - else - echo " â­ī¸ Skipping latest (auto mode, no version change)" fi echo " 🚀 Publishing next: @dotcms/${sdk}@${NEXT_VERSION}" @@ -275,20 +219,6 @@ runs: echo "::endgroup::" shell: bash - - name: 'Commit and push VERSION bump' - if: ${{ steps.set_versions.outputs.should_publish_latest == 'true' && steps.publish_packages.outputs.actual_published_latest == 'true' }} - working-directory: ${{ github.workspace }}/core-web/libs/sdk/ - env: - LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} - run: | - echo "$LATEST_VERSION" > VERSION - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add VERSION - git commit -m "chore(sdk): bump SDK version to $LATEST_VERSION" - git push - shell: bash - - name: 'Set output' id: deployment_status if: success() @@ -296,7 +226,8 @@ runs: ACTUAL_PUBLISHED_LATEST: ${{ steps.publish_packages.outputs.actual_published_latest }} ACTUAL_PUBLISHED_NEXT: ${{ steps.publish_packages.outputs.actual_published_next }} LATEST_VERSION: ${{ steps.set_versions.outputs.latest_version }} - NEXT_VERSION: ${{ steps.set_versions.outputs.next_version_next }} + NEXT_VERSION: ${{ steps.set_versions.outputs.next_version }} + PUBLISH_LATEST: ${{ inputs.publish-latest }} run: | echo "published_latest=$ACTUAL_PUBLISHED_LATEST" >> $GITHUB_OUTPUT echo "published_next=$ACTUAL_PUBLISHED_NEXT" >> $GITHUB_OUTPUT @@ -308,9 +239,9 @@ runs: fi echo "published=$PUBLISHED" >> $GITHUB_OUTPUT - if [ "$ACTUAL_PUBLISHED_LATEST" = "true" ] && [ "$ACTUAL_PUBLISHED_NEXT" = "true" ]; then + if [ "$PUBLISH_LATEST" = "true" ] && [ "$ACTUAL_PUBLISHED_LATEST" = "true" ] && [ "$ACTUAL_PUBLISHED_NEXT" = "true" ]; then NPM_PACKAGE_VERSION="${LATEST_VERSION} (latest) and ${NEXT_VERSION} (next)" - elif [ "$ACTUAL_PUBLISHED_LATEST" = "true" ]; then + elif [ "$PUBLISH_LATEST" = "true" ] && [ "$ACTUAL_PUBLISHED_LATEST" = "true" ]; then NPM_PACKAGE_VERSION="${LATEST_VERSION} (latest)" elif [ "$ACTUAL_PUBLISHED_NEXT" = "true" ]; then NPM_PACKAGE_VERSION="${NEXT_VERSION} (next)" diff --git a/.github/workflows/cicd_manual-release-sdks.yml b/.github/workflows/cicd_manual-release-sdks.yml index af8f37239ab2..6ce0cd08a96c 100644 --- a/.github/workflows/cicd_manual-release-sdks.yml +++ b/.github/workflows/cicd_manual-release-sdks.yml @@ -18,11 +18,6 @@ on: required: false type: string default: '' - ref: - description: 'Branch to build from' - required: false - type: string - default: 'main' jobs: release-sdks: @@ -30,20 +25,21 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + pull-requests: write steps: - - name: 'Checkout repository' + - name: 'Checkout main' uses: actions/checkout@v4 with: - ref: ${{ inputs.ref }} + ref: main token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 - name: 'Validate inputs' run: | echo "::group::Input validation" echo "Version type: ${{ inputs.version-type }}" echo "Custom version: ${{ inputs.custom-version }}" - echo "Branch: ${{ inputs.ref }}" if [ "${{ inputs.version-type }}" = "custom" ]; then if [ -z "${{ inputs.custom-version }}" ]; then @@ -58,24 +54,95 @@ jobs: fi echo "::endgroup::" - - name: 'Deploy JavaScript SDK' + - name: 'Compute release version' + id: compute_version + run: | + set -euo pipefail + CURRENT=$(cat core-web/libs/sdk/VERSION | tr -d '[:space:]') + echo "Current VERSION: $CURRENT" + + IFS='.' read -ra PARTS <<< "$CURRENT" + MAJOR=${PARTS[0]}; MINOR=${PARTS[1]}; PATCH=${PARTS[2]} + + case "${{ inputs.version-type }}" in + major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;; + minor) MINOR=$((MINOR + 1)); PATCH=0 ;; + patch) PATCH=$((PATCH + 1)) ;; + custom) + IFS='.' read -ra CPARTS <<< "${{ inputs.custom-version }}" + MAJOR=${CPARTS[0]}; MINOR=${CPARTS[1]}; PATCH=${CPARTS[2]} + ;; + esac + + RELEASE_VERSION="${MAJOR}.${MINOR}.${PATCH}" + NEXT_DEV_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" + + if [ "$RELEASE_VERSION" = "$CURRENT" ]; then + echo "::error::Computed release version '$RELEASE_VERSION' matches current VERSION. Choose a different version." + exit 1 + fi + + echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT + echo "next_dev_version=$NEXT_DEV_VERSION" >> $GITHUB_OUTPUT + echo "release_branch=sdk/release-${RELEASE_VERSION}" >> $GITHUB_OUTPUT + echo "Release: $RELEASE_VERSION, Next dev: $NEXT_DEV_VERSION" + + - name: 'Create release branch and bump VERSION' + env: + RELEASE_VERSION: ${{ steps.compute_version.outputs.release_version }} + RELEASE_BRANCH: ${{ steps.compute_version.outputs.release_branch }} + run: | + set -euo pipefail + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git checkout -b "$RELEASE_BRANCH" + echo "$RELEASE_VERSION" > core-web/libs/sdk/VERSION + git add core-web/libs/sdk/VERSION + git commit -m "chore(sdk): bump SDK version to $RELEASE_VERSION" + git push origin "$RELEASE_BRANCH" + + - name: 'Publish @latest from release branch' id: deploy-javascript-sdk uses: ./.github/actions/core-cicd/deployment/deploy-javascript-sdk with: - ref: ${{ inputs.ref }} + ref: ${{ steps.compute_version.outputs.release_branch }} npm-token: ${{ secrets.NPM_ORG_TOKEN }} - npm-package-tag: 'latest' - version-type: ${{ inputs.version-type }} - custom-version: ${{ inputs.custom-version }} + publish-latest: 'true' github-token: ${{ secrets.GITHUB_TOKEN }} + - name: 'Open post-release PR to bump VERSION on main' + env: + RELEASE_VERSION: ${{ steps.compute_version.outputs.release_version }} + NEXT_DEV_VERSION: ${{ steps.compute_version.outputs.next_dev_version }} + RELEASE_BRANCH: ${{ steps.compute_version.outputs.release_branch }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + PR_BRANCH="sdk/post-release-${RELEASE_VERSION}" + git checkout main + git checkout -b "$PR_BRANCH" + echo "$NEXT_DEV_VERSION" > core-web/libs/sdk/VERSION + git add core-web/libs/sdk/VERSION + git commit -m "chore(sdk): bump SDK version to $NEXT_DEV_VERSION after $RELEASE_VERSION release" + git push origin "$PR_BRANCH" + + gh pr create \ + --title "chore(sdk): bump SDK version to $NEXT_DEV_VERSION after $RELEASE_VERSION release" \ + --body "Automated post-release bump. Moves the VERSION file from \`$RELEASE_VERSION\` to \`$NEXT_DEV_VERSION\` so trunk \`@next\` builds stay ahead of \`@latest\`." \ + --base main \ + --head "$PR_BRANCH" + - name: 'Display results' if: always() run: | echo "::group::Release Summary" - echo "Version type used: ${{ steps.deploy-javascript-sdk.outputs.version-type-used || inputs.version-type }}" + echo "Release version: ${{ steps.compute_version.outputs.release_version }}" + echo "Next dev version: ${{ steps.compute_version.outputs.next_dev_version }}" echo "Published to latest: ${{ steps.deploy-javascript-sdk.outputs.published-latest || 'unknown' }}" - echo "Published to next: ${{ steps.deploy-javascript-sdk.outputs.published-next || 'unknown' }}" + echo "Published to next: ${{ steps.deploy-javascript-sdk.outputs.published-next || 'unknown' }}" echo "NPM package version: ${{ steps.deploy-javascript-sdk.outputs.npm-package-version || 'unknown' }}" - echo "Next version: ${{ steps.deploy-javascript-sdk.outputs.npm-package-version-next || 'unknown' }}" echo "::endgroup::" From a7758af9a9d00d9b1f441add9c427070465d36c3 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Thu, 16 Apr 2026 18:44:48 -0600 Subject: [PATCH 7/8] fix(sdk): address third round of Copilot review comments - Remove unused npm-package-tag input from action (tags are hardcoded to latest/next and the input was never wired up) - Add set -euo pipefail to publish step so jq failures fail fast - Add VERSION file existence and semver validation in manual workflow before arithmetic to give a clear error on malformed input - Reset and clean workspace before git checkout main in post-release step so dirty package.json files from the publish action don't block the branch switch Co-Authored-By: Claude Sonnet 4.6 --- .../deployment/deploy-javascript-sdk/action.yml | 5 +---- .github/workflows/cicd_manual-release-sdks.yml | 13 +++++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml index fe67a4647a48..fbf7dfa1a5c4 100644 --- a/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml +++ b/.github/actions/core-cicd/deployment/deploy-javascript-sdk/action.yml @@ -15,10 +15,6 @@ inputs: npm-token: description: 'NPM token' required: true - npm-package-tag: - description: 'Package tag (latest or next)' - required: false - default: 'next' publish-latest: description: 'Whether to publish the @latest tag in addition to @next' required: false @@ -165,6 +161,7 @@ runs: NPM_AUTH_TOKEN: ${{ inputs.npm-token }} PUBLISH_LATEST: ${{ inputs.publish-latest }} run: | + set -euo pipefail echo "::group::Publishing SDK packages" echo "Latest: $LATEST_VERSION (publish: $PUBLISH_LATEST)" echo "Next: $NEXT_VERSION" diff --git a/.github/workflows/cicd_manual-release-sdks.yml b/.github/workflows/cicd_manual-release-sdks.yml index 6ce0cd08a96c..990b697916d5 100644 --- a/.github/workflows/cicd_manual-release-sdks.yml +++ b/.github/workflows/cicd_manual-release-sdks.yml @@ -58,9 +58,18 @@ jobs: id: compute_version run: | set -euo pipefail + if [ ! -f "core-web/libs/sdk/VERSION" ]; then + echo "::error::VERSION file not found at core-web/libs/sdk/VERSION" + exit 1 + fi CURRENT=$(cat core-web/libs/sdk/VERSION | tr -d '[:space:]') echo "Current VERSION: $CURRENT" + if [[ ! "$CURRENT" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "::error::Invalid version in VERSION file: '$CURRENT'. Must be semver (e.g. 1.2.6)" + exit 1 + fi + IFS='.' read -ra PARTS <<< "$CURRENT" MAJOR=${PARTS[0]}; MINOR=${PARTS[1]}; PATCH=${PARTS[2]} @@ -123,7 +132,11 @@ jobs: git config user.email "github-actions[bot]@users.noreply.github.com" PR_BRANCH="sdk/post-release-${RELEASE_VERSION}" + git reset --hard + git clean -fdx + git fetch origin main git checkout main + git reset --hard origin/main git checkout -b "$PR_BRANCH" echo "$NEXT_DEV_VERSION" > core-web/libs/sdk/VERSION git add core-web/libs/sdk/VERSION From c28bbc1d0803dac9752bc5cca0c6c008d7264512 Mon Sep 17 00:00:00 2001 From: Freddy Montes Date: Fri, 17 Apr 2026 08:03:12 -0600 Subject: [PATCH 8/8] chore(sdk): update VERSION to 1.5.1 (ahead of latest 1.5.0) --- core-web/libs/sdk/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-web/libs/sdk/VERSION b/core-web/libs/sdk/VERSION index 3c43790f5d82..26ca594609a9 100644 --- a/core-web/libs/sdk/VERSION +++ b/core-web/libs/sdk/VERSION @@ -1 +1 @@ -1.2.6 +1.5.1