diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index efbe7b8b2a2..dfb2df72188 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,6 +5,25 @@ on: push: branches: # White-list of deployable tags and branches. Note that all white-listed branches cannot include any `/` characters - next + workflow_dispatch: + inputs: + dry_run: + description: 'Skip NPM publish, tagging, and docs (for testing the workflow)' + type: boolean + default: true + pr_number: + description: 'PR number to comment on (for testing the comment logic)' + type: string + default: '' + test_version: + description: 'Version for comment (e.g., v3.5.0-next.1)' + type: string + default: '' + test_packages: + description: 'Packages for comment (e.g., {webex,@webex/plugin-meetings})' + type: string + default: '' + env: rid: ${{ github.run_id }}-${{ github.run_number }} @@ -123,22 +142,42 @@ jobs: # Used for running node scripts against all changed packages since the last push to the target branch. - id: generate-package-matrix-node-changed name: Generate Package Matrix - run: echo "node-changed=$(yarn package-tools list --mode node --since ${{ github.event.before }})" >> $GITHUB_OUTPUT + run: | + SINCE="${{ github.event.before }}" + if [ -z "$SINCE" ] || [ "$SINCE" = "0000000000000000000000000000000000000000" ]; then + SINCE=$(git rev-parse HEAD~1) + fi + echo "node-changed=$(yarn package-tools list --mode node --since $SINCE)" >> $GITHUB_OUTPUT # Used for running node scripts against all changed packages, and their dependents, since the last push to the target branch. - id: generate-package-matrix-node-recursive name: Generate Package Matrix - run: echo "node-recursive=$(yarn package-tools list --mode node --recursive --since ${{ github.event.before }})" >> $GITHUB_OUTPUT + run: | + SINCE="${{ github.event.before }}" + if [ -z "$SINCE" ] || [ "$SINCE" = "0000000000000000000000000000000000000000" ]; then + SINCE=$(git rev-parse HEAD~1) + fi + echo "node-recursive=$(yarn package-tools list --mode node --recursive --since $SINCE)" >> $GITHUB_OUTPUT # Used for running yarn tools against all changed packages since the last push to the target branch. - id: generate-package-matrix-yarn-changed name: Generate Package Matrix - run: echo "yarn-changed=$(yarn package-tools list --since ${{ github.event.before }})" >> $GITHUB_OUTPUT + run: | + SINCE="${{ github.event.before }}" + if [ -z "$SINCE" ] || [ "$SINCE" = "0000000000000000000000000000000000000000" ]; then + SINCE=$(git rev-parse HEAD~1) + fi + echo "yarn-changed=$(yarn package-tools list --since $SINCE)" >> $GITHUB_OUTPUT # Used for running yarn tools against all changed packages, and their dependents, since the last push to the target branch. - id: generate-package-matrix-yarn-recursive name: Generate Package Matrix - run: echo "yarn-recursive=$(yarn package-tools list --recursive --since ${{ github.event.before }})" >> $GITHUB_OUTPUT + run: | + SINCE="${{ github.event.before }}" + if [ -z "$SINCE" ] || [ "$SINCE" = "0000000000000000000000000000000000000000" ]; then + SINCE=$(git rev-parse HEAD~1) + fi + echo "yarn-recursive=$(yarn package-tools list --recursive --since $SINCE)" >> $GITHUB_OUTPUT - name: Display Package Matrix run: | @@ -152,6 +191,7 @@ jobs: name: Publish - NPM needs: generate-package-matrix runs-on: ubuntu-latest + if: ${{ github.event_name == 'push' || inputs.dry_run != true }} steps: - name: Checkout Project @@ -208,7 +248,7 @@ jobs: name: Publish - Documentation needs: [publish-npm,generate-package-matrix] runs-on: ubuntu-latest - if: github.ref != 'refs/heads/wxcc' + if: ${{ github.ref != 'refs/heads/wxcc' && (github.event_name == 'push' || inputs.dry_run != true) }} steps: - name: Documentation Deploy Steps @@ -278,12 +318,15 @@ jobs: name: Publish - Tags runs-on: ubuntu-latest needs: [generate-package-matrix, publish-npm] + if: ${{ github.event_name == 'push' || inputs.dry_run != true }} outputs: message: ${{ steps.versionextractor.outputs.message }} version: ${{ steps.versionextractor.outputs.version }} commit: ${{ steps.lastcommit.outputs.commit }} proceed: ${{ steps.skipcondition.outputs.proceed }} + package_name: ${{ steps.changedpackage.outputs.package_name }} + package_version: ${{ steps.changedpackage.outputs.package_version }} steps: - name: Checkout Project @@ -318,6 +361,23 @@ jobs: echo "message=$(git log -1 --oneline --no-decorate)" >> $GITHUB_OUTPUT echo "version=v$(yarn package-tools sync --tag ${GITHUB_REF##*/} --packages webex | awk '{print $3}' | tr -d '%')" >> $GITHUB_OUTPUT + - name: Extract changed package version + id: changedpackage + run: | + PACKAGES="${{ needs.generate-package-matrix.outputs.node-recursive }}" + CLEAN=$(echo "$PACKAGES" | tr -d '{}') + if echo "$CLEAN" | tr ',' '\n' | grep -q "^webex$"; then + PKG="webex" + else + PKG=$(echo "$CLEAN" | tr ',' '\n' | head -1 | tr -d ' ') + fi + if [ -n "$PKG" ]; then + PKG_VERSION=$(yarn package-tools sync --tag ${GITHUB_REF##*/} --packages $PKG | awk '{print $3}' | tr -d '%') + echo "package_name=${PKG}" >> $GITHUB_OUTPUT + echo "package_version=v${PKG_VERSION}" >> $GITHUB_OUTPUT + echo "๐Ÿ“ฆ Selected package: ${PKG} version: ${PKG_VERSION}" + fi + - name: Conditions to skip tag publish id: skipcondition run: | @@ -365,3 +425,143 @@ jobs: else git push origin ${{ steps.versionextractor.outputs.version }} fi + + comment-on-prs: + name: Comment on Merged PR + needs: [publish-tag, generate-package-matrix] + runs-on: ubuntu-latest + if: | + always() && + needs.generate-package-matrix.result == 'success' && + (needs.generate-package-matrix.outputs.node-recursive != '' || inputs.pr_number != '') + + steps: + - name: Checkout Project + uses: actions/checkout@v3 + + - name: Get Pull Request Number + id: pr + run: | + if [ -n "${{ inputs.pr_number }}" ]; then + echo "pull_request_number=${{ inputs.pr_number }}" >> $GITHUB_OUTPUT + else + echo "pull_request_number=$(gh pr view --json number -q .number || echo "")" >> $GITHUB_OUTPUT + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Auto-detect Version from Tags + id: tag-version + run: | + git fetch --tags origin next + VERSION=$(git describe --tags --abbrev=0 origin/next 2>/dev/null || echo "") + echo "๐Ÿ“‹ Auto-detected version from tags: ${VERSION}" + echo "version=${VERSION}" >> $GITHUB_OUTPUT + + - name: Auto-detect Packages from PR + id: pr-packages + if: ${{ steps.pr.outputs.pull_request_number != '' }} + uses: actions/github-script@v7 + with: + script: | + const prNumber = parseInt('${{ steps.pr.outputs.pull_request_number }}'); + console.log(`๐Ÿ“‹ Detecting packages from PR #${prNumber} files...`); + + const files = await github.paginate(github.rest.pulls.listFiles, { + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber, + per_page: 100 + }); + + const packages = new Set(); + for (const file of files) { + if (!file.filename.startsWith('packages/')) continue; + const parts = file.filename.split('/'); + if (parts[1] === '@webex' && parts.length >= 3) { + packages.add(`@webex/${parts[2]}`); + } else if (parts.length >= 2) { + packages.add(parts[1]); + } + } + if (packages.size === 0) packages.add('webex'); + + const pkgList = Array.from(packages); + const primary = pkgList.includes('webex') ? 'webex' : pkgList[0]; + console.log(`๐Ÿ“‹ Auto-detected packages: ${pkgList.join(', ')}`); + console.log(`๐Ÿ“‹ Primary package: ${primary}`); + core.setOutput('packages', `{${pkgList.join(',')}}`); + core.setOutput('primary_package', primary); + + - name: Post Comment on PR + if: ${{ steps.pr.outputs.pull_request_number != '' }} + uses: actions/github-script@v7 + env: + INPUT_VERSION: ${{ needs.publish-tag.outputs.package_version || steps.tag-version.outputs.version || 'v0.0.0-dry-run' }} + INPUT_PACKAGES: ${{ needs.generate-package-matrix.outputs.node-recursive || steps.pr-packages.outputs.packages || 'webex' }} + INPUT_PR_NUMBER: ${{ steps.pr.outputs.pull_request_number }} + INPUT_PACKAGE_NAME: ${{ needs.publish-tag.outputs.package_name || steps.pr-packages.outputs.primary_package || 'webex' }} + with: + script: | + const version = process.env.INPUT_VERSION || ''; + const versionNumber = version.replace(/^v/, ''); + const prNumber = parseInt(process.env.INPUT_PR_NUMBER); + + if (!prNumber) { + console.log('No PR number found, skipping'); + return; + } + + console.log(`Posting comment on PR #${prNumber} for version ${version}`); + + const existingComments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber + }); + + const alreadyCommented = existingComments.data.some(c => + c.user.type === 'Bot' && + c.body.includes('Your changes are now available') && + c.body.includes(version) + ); + + if (alreadyCommented) { + console.log(`Already commented on PR #${prNumber} for ${version}`); + return; + } + + const packagesRaw = process.env.INPUT_PACKAGES || ''; + const packages = packagesRaw + .replace(/[{}]/g, '') + .split(',') + .map(p => p.trim()) + .filter(Boolean); + + const primaryPackage = process.env.INPUT_PACKAGE_NAME || 'webex'; + const packageList = packages.slice(0, 5).map(p => `\`${p}\``).join(', '); + const morePackages = packages.length > 5 ? ` and ${packages.length - 5} more` : ''; + + const stableVersion = versionNumber.replace(/-next\..*$/, ''); + const changelogUrl = `https://web-sdk.webex.com/changelog/?stable_version=${stableVersion}&package=${primaryPackage}&version=${versionNumber}`; + + const commentBody = [ + '## ๐ŸŽ‰ Your changes are now available!', + '', + `**Released in:** [\`${version}\`](https://github.com/${context.repo.owner}/${context.repo.repo}/releases/tag/${version})`, + `**Packages updated:** ${packageList}${morePackages}`, + '', + `๐Ÿ“– **[View full changelog โ†’](${changelogUrl})**`, + '', + '---', + `๐Ÿค– This is an automated message.` + ].join('\n'); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: commentBody + }); + + console.log(`โœ… Commented on PR #${prNumber}`); diff --git a/.github/workflows/pr-comment-bot.yml b/.github/workflows/pr-comment-bot.yml deleted file mode 100644 index ed49d303205..00000000000 --- a/.github/workflows/pr-comment-bot.yml +++ /dev/null @@ -1,257 +0,0 @@ -name: PR Release Comment Bot -run-name: ${{ github.actor }} triggered release comment bot - -on: - workflow_dispatch: - inputs: - test_version: - description: 'Test version number (e.g., 3.4.0)' - required: false - default: '3.4.0' - test_pr_number: - description: 'Test PR number (e.g., 2) - leave empty to auto-detect' - required: false - default: '' - workflow_run: - workflows: ["Deploy CD"] - types: - - completed - branches: - - next - -jobs: - comment-on-prs: - name: Comment on Released PRs - runs-on: ubuntu-latest - # Only run if manually triggered or Deploy CD succeeded - if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} - - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Fetch all history to find commits - - - name: Get Version and PR from Tag - id: tag-info - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - VERSION="${{ github.event.inputs.test_version }}" - PR_NUMBER="${{ github.event.inputs.test_pr_number }}" - echo "๐Ÿงช TEST MODE: version=${VERSION}, pr=${PR_NUMBER}" - else - git fetch --tags - VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo "") - if [ -z "$VERSION" ]; then - echo "โŒ No tags found" - exit 1 - fi - TAG_MESSAGE=$(git tag -l --format='%(contents:subject)' "$VERSION") - PR_NUMBER=$(echo "$TAG_MESSAGE" | grep -oE '#[0-9]+' | head -1 | tr -d '#') - echo "๐Ÿ“ฆ Tag: ${VERSION}, PR: #${PR_NUMBER}" - fi - - echo "version=${VERSION}" >> $GITHUB_OUTPUT - echo "version_number=${VERSION#v}" >> $GITHUB_OUTPUT - echo "pr_number=${PR_NUMBER}" >> $GITHUB_OUTPUT - - - name: Get Packages from PR - id: get-prs - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const path = require('path'); - const prNumber = '${{ steps.tag-info.outputs.pr_number }}'; - - if (!prNumber) { - console.log('โŒ No PR number found from tag, skipping'); - core.setOutput('pr_numbers', JSON.stringify([])); - core.setOutput('packages', JSON.stringify([])); - core.setOutput('package_versions', JSON.stringify({})); - core.setOutput('primary_package', ''); - core.setOutput('primary_package_version', ''); - core.setOutput('commit_count', '0'); - return { prs: [], packages: [] }; - } - - console.log(`โœ… Using PR #${prNumber} from tag`); - - const { packages, packageVersions, primaryPackage, primaryPackageVersion } = - await getPackagesForPr(prNumber); - - core.setOutput('pr_numbers', JSON.stringify([prNumber])); - core.setOutput('packages', JSON.stringify(packages)); - core.setOutput('package_versions', JSON.stringify(packageVersions)); - core.setOutput('primary_package', primaryPackage); - core.setOutput('primary_package_version', primaryPackageVersion); - core.setOutput('commit_count', '1'); - - return { prs: [prNumber], packages: packages }; - - async function getPackagesForPr(prNumber) { - const packageSet = new Set(); - try { - const files = await github.paginate(github.rest.pulls.listFiles, { - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: parseInt(prNumber, 10), - per_page: 100 - }); - - for (const file of files) { - const filename = file.filename; - if (!filename.startsWith('packages/')) { - continue; - } - - const parts = filename.split('/'); - if (parts[1] === '@webex' && parts.length >= 3) { - packageSet.add(`@webex/${parts[2]}`); - } else if (parts.length >= 2) { - packageSet.add(parts[1]); - } - } - } catch (error) { - console.log(`Error listing PR files: ${error.message}`); - } - - if (packageSet.size === 0) { - packageSet.add('webex'); - } - - const packages = Array.from(packageSet); - const packageVersions = {}; - - for (const packageName of packages) { - const packageJsonPath = packageName.startsWith('@webex/') - ? path.join(process.env.GITHUB_WORKSPACE, 'packages', '@webex', packageName.split('/')[1], 'package.json') - : path.join(process.env.GITHUB_WORKSPACE, 'packages', packageName, 'package.json'); - - try { - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - if (packageJson.version) { - packageVersions[packageName] = packageJson.version; - } - } catch (error) { - console.log(`Error reading ${packageJsonPath}: ${error.message}`); - } - } - - const primaryPackage = packages[0] || ''; - const primaryPackageVersion = primaryPackage ? (packageVersions[primaryPackage] || '') : ''; - - return { packages, packageVersions, primaryPackage, primaryPackageVersion }; - } - - - name: Post Release Comment on PR - uses: actions/github-script@v7 - with: - script: | - const version = '${{ steps.tag-info.outputs.version }}'; - const versionNumber = '${{ steps.tag-info.outputs.version_number }}'; - const stableVersion = versionNumber.replace(/-next\..*$/, ''); - const prNumbersRaw = '${{ steps.get-prs.outputs.pr_numbers }}'; - const packagesRaw = '${{ steps.get-prs.outputs.packages }}'; - const packageVersionsRaw = '${{ steps.get-prs.outputs.package_versions }}'; - const primaryPackage = '${{ steps.get-prs.outputs.primary_package }}'; - const primaryPackageVersion = '${{ steps.get-prs.outputs.primary_package_version }}'; - const prNumbers = prNumbersRaw ? JSON.parse(prNumbersRaw) : []; - const packages = packagesRaw ? JSON.parse(packagesRaw) : []; - const packageVersions = packageVersionsRaw ? JSON.parse(packageVersionsRaw) : {}; - - const prNumber = prNumbers[0]; - console.log(`Posting comment to PR #${prNumber}`); - - if (prNumbers.length === 0) { - console.log('No PRs found to comment on'); - return; - } - - // Build the changelog URL - // If 'webex' package is in the list, use it. Otherwise use the first detected package. - const hasWebexPackage = packages.includes('webex'); - const changelogPackage = hasWebexPackage ? 'webex' : packages[0]; - - const changelogUrl = new URL('https://web-sdk.webex.com/changelog/'); - changelogUrl.searchParams.set('stable_version', stableVersion); - changelogUrl.searchParams.set('package', changelogPackage); - changelogUrl.searchParams.set('version', versionNumber); - - console.log(`๐Ÿ“ฆ Changelog URL package: ${changelogPackage}`); - console.log(`๐Ÿ“ฆ Changelog URL version: ${versionNumber}`); - console.log(`๐Ÿ”— Full URL: ${changelogUrl.toString()}`); - - // Build the package list markdown - const packageList = packages.slice(0, 5).map(p => `\`${p}\``).join(', '); - const morePackages = packages.length > 5 ? ` and ${packages.length - 5} more` : ''; - - // Create the comment body - const commentBody = [ - '## ๐ŸŽ‰ Your changes are now available!', - '', - `**Released in:** [\`${version}\`](https://github.com/${context.repo.owner}/${context.repo.repo}/releases/tag/${version})`, - `**Packages updated:** ${packageList}${morePackages}`, - '', - `๐Ÿ“– **[View full changelog โ†’](${changelogUrl})**`, - '', - `Thank you for your contribution!`, - '', - '---', - `๐Ÿค– This is an automated message. For questions, please refer to the [documentation](https://github.com/${context.repo.owner}/${context.repo.repo}#readme).` - ].join('\n'); - - try { - console.log(`Commenting on PR #${prNumber}`); - - // Check if PR exists and is merged - let pr; - try { - pr = await github.rest.pulls.get({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: parseInt(prNumber) - }); - } catch (error) { - console.log(`PR #${prNumber} not found or error: ${error.message}`); - return; - } - - if (!pr.data.merged_at) { - console.log(`PR #${prNumber} is not merged, skipping`); - return; - } - - // Check if we've already commented (to avoid duplicates) - const existingComments = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: parseInt(prNumber) - }); - - const botCommentExists = existingComments.data.some(comment => - comment.user.type === 'Bot' && - comment.body.includes('Your changes are now available') && - comment.body.includes(version) - ); - - if (botCommentExists) { - console.log(`Already commented on PR #${prNumber} for version ${version}`); - return; - } - - // Post the comment - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: parseInt(prNumber), - body: commentBody - }); - - console.log(`โœ… Successfully commented on PR #${prNumber}`); - } catch (error) { - console.error(`Failed to comment on PR #${prNumber}:`, error.message); - } - - console.log('โœจ Comment posted successfully!'); - diff --git a/.github/workflows/test-comment.yml b/.github/workflows/test-comment.yml new file mode 100644 index 00000000000..c7f4f48452d --- /dev/null +++ b/.github/workflows/test-comment.yml @@ -0,0 +1,156 @@ +name: Test Comment Logic +run-name: ${{ github.actor }} testing comment logic + +on: + workflow_dispatch: + inputs: + pr_number: + description: 'PR number to comment on' + required: true + +jobs: + test-comment: + name: Test Comment on PR + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v3.7.0 + with: + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' + cache: 'yarn' + + - name: Install Dependencies + run: yarn + + - name: Build Tools + run: yarn workspaces foreach --from '@webex/*-tools' --topological-dev --parallel --verbose run build:src + + - name: Build Webex Core + run: yarn workspace @webex/webex-core run build:src + + - name: Build Other Packages + run: yarn workspaces foreach --parallel --topological --verbose run build:src + + - name: Auto-detect Version from Tags + id: tag-version + run: | + echo "๐Ÿ“‹ Adding upstream remote..." + git remote add upstream https://github.com/webex/webex-js-sdk.git || true + echo "๐Ÿ“‹ Fetching tags from upstream/next..." + git fetch --tags upstream next + echo "๐Ÿ“‹ Latest 5 tags on upstream/next:" + git tag --sort=-v:refname --merged upstream/next | head -5 + + VERSION=$(git describe --tags --abbrev=0 upstream/next 2>/dev/null || echo "") + echo "๐Ÿ“‹ Auto-detected version: ${VERSION}" + echo "version=${VERSION}" >> $GITHUB_OUTPUT + + - name: Detect Changed Packages + id: pr-packages + run: | + echo "๐Ÿ“‹ Fetching full branch history..." + git fetch origin ${GITHUB_REF##*/} --unshallow || true + + SINCE=$(git rev-parse HEAD~1) + echo "๐Ÿ“‹ Detecting packages since commit: ${SINCE}" + + NODE_RECURSIVE=$(yarn package-tools list --mode node --recursive --since $SINCE) + echo "๐Ÿ“‹ Changed packages (node-recursive): ${NODE_RECURSIVE}" + echo "packages=${NODE_RECURSIVE}" >> $GITHUB_OUTPUT + + FIRST_PACKAGE=$(echo "${NODE_RECURSIVE}" | sed 's/[{}]//g' | cut -d',' -f1 | tr -d ' ') + if [ -z "$FIRST_PACKAGE" ]; then + FIRST_PACKAGE="webex" + fi + echo "๐Ÿ“‹ Primary package: ${FIRST_PACKAGE}" + echo "primary_package=${FIRST_PACKAGE}" >> $GITHUB_OUTPUT + + - name: Post Comment on PR + uses: actions/github-script@v7 + env: + INPUT_VERSION: ${{ steps.tag-version.outputs.version }} + INPUT_PACKAGES: ${{ steps.pr-packages.outputs.packages }} + INPUT_PR_NUMBER: ${{ inputs.pr_number }} + INPUT_PACKAGE_NAME: ${{ steps.pr-packages.outputs.primary_package }} + with: + script: | + const version = process.env.INPUT_VERSION || ''; + const versionNumber = version.replace(/^v/, ''); + const prNumber = parseInt(process.env.INPUT_PR_NUMBER); + + if (!prNumber) { + console.log('No PR number found, skipping'); + return; + } + + console.log(`Posting comment on PR #${prNumber} for version ${version}`); + + const existingComments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber + }); + + const alreadyCommented = existingComments.data.some(c => + c.user.type === 'Bot' && + c.body.includes('Your changes are now available') && + c.body.includes(version) + ); + + if (alreadyCommented) { + console.log(`Already commented on PR #${prNumber} for ${version}`); + return; + } + + const packagesRaw = process.env.INPUT_PACKAGES || ''; + const packages = packagesRaw + .replace(/[{}]/g, '') + .split(',') + .map(p => p.trim()) + .filter(Boolean); + + const primaryPackage = process.env.INPUT_PACKAGE_NAME || 'webex'; + const packageList = packages.slice(0, 5).map(p => `\`${p}\``).join(', '); + const morePackages = packages.length > 5 ? ` and ${packages.length - 5} more` : ''; + + const stableVersion = versionNumber.replace(/-next\..*$/, ''); + const changelogUrl = `https://web-sdk.webex.com/changelog/?stable_version=${stableVersion}&package=${primaryPackage}&version=${versionNumber}`; + + console.log(`๐Ÿ“‹ Final values:`); + console.log(` Version: ${version}`); + console.log(` Version Number: ${versionNumber}`); + console.log(` Stable Version: ${stableVersion}`); + console.log(` Primary Package: ${primaryPackage}`); + console.log(` Packages: ${packageList}`); + console.log(` Changelog URL: ${changelogUrl}`); + + const commentBody = [ + '## ๐ŸŽ‰ Your changes are now available!', + '', + `**Released in:** [\`${version}\`](https://github.com/${context.repo.owner}/${context.repo.repo}/releases/tag/${version})`, + `**Packages updated:** ${packageList}${morePackages}`, + '', + `๐Ÿ“– **[View full changelog โ†’](${changelogUrl})**`, + '', + '---', + `๐Ÿค– This is an automated message.` + ].join('\n'); + + console.log(`๐Ÿ“‹ Comment body preview:`); + console.log(commentBody); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: commentBody + }); + + console.log(`โœ… Commented on PR #${prNumber}`);