Publish to npm #147
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish to npm | |
| on: | |
| workflow_run: | |
| workflows: ["CI"] | |
| types: [completed] | |
| branches: ['release/**'] | |
| schedule: | |
| - cron: '0 2 * * 1-5' # Weekdays at 2 AM UTC (Mon-Fri) | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: 'Release type (ignored for release branch workflow_run — always stable)' | |
| required: true | |
| default: 'nightly' | |
| type: choice | |
| options: | |
| - nightly | |
| - stable | |
| env: | |
| SFCC_DISABLE_TELEMETRY: ${{ vars.SFCC_DISABLE_TELEMETRY }} | |
| jobs: | |
| publish: | |
| name: Publish | |
| runs-on: ubuntu-latest | |
| if: >- | |
| github.event_name != 'workflow_run' || | |
| github.event.workflow_run.conclusion == 'success' | |
| permissions: | |
| actions: write # For triggering deploy-docs.yml via workflow_dispatch | |
| contents: write # For creating GitHub releases and tags | |
| id-token: write # Required for npm OIDC trusted publishers | |
| pull-requests: write # For creating merge-back PRs | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_branch || '' }} | |
| fetch-depth: 0 # Needed for docs tag detection | |
| - name: Determine release type | |
| id: release-type | |
| run: | | |
| if [[ "${{ github.event.inputs.release_type }}" == "stable" ]] || [[ "${{ github.event_name }}" == "workflow_run" ]]; then | |
| echo "type=stable" >> $GITHUB_OUTPUT | |
| echo "tag=latest" >> $GITHUB_OUTPUT | |
| else | |
| echo "type=nightly" >> $GITHUB_OUTPUT | |
| echo "tag=nightly" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Check for pending changesets | |
| if: steps.release-type.outputs.type == 'stable' | |
| id: changesets | |
| run: | | |
| PENDING=$(find .changeset -name '*.md' ! -name 'README.md' 2>/dev/null | wc -l | tr -d ' ') | |
| if [[ "$PENDING" -gt 0 ]]; then | |
| echo "skip=true" >> $GITHUB_OUTPUT | |
| echo "::notice::Found $PENDING pending changeset(s) — skipping publish" | |
| else | |
| echo "skip=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Quick version check | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' | |
| id: quick-check | |
| run: | | |
| HAS_CHANGES=false | |
| for spec in "@salesforce/b2c-tooling-sdk:packages/b2c-tooling-sdk" \ | |
| "@salesforce/b2c-cli:packages/b2c-cli" \ | |
| "@salesforce/b2c-dx-mcp:packages/b2c-dx-mcp" \ | |
| "@salesforce/mrt-utilities:packages/mrt-utilities"; do | |
| PKG_NAME="${spec%%:*}" | |
| PKG_PATH="${spec##*:}" | |
| LOCAL=$(node -p "require('./${PKG_PATH}/package.json').version") | |
| NPM=$(npm view "$PKG_NAME" version 2>/dev/null || echo "0.0.0") | |
| if [ "$LOCAL" != "$NPM" ]; then | |
| HAS_CHANGES=true | |
| break | |
| fi | |
| done | |
| # Also check VS extension tag | |
| if [ "$HAS_CHANGES" = "false" ]; then | |
| VSX_VERSION=$(node -p "require('./packages/b2c-vs-extension/package.json').version") | |
| LAST_VSX_TAG=$(git tag -l "b2c-vs-extension@*" --sort=-v:refname | grep -v '@latest$' | head -1 | sed 's/b2c-vs-extension@//') | |
| if [ "$VSX_VERSION" != "$LAST_VSX_TAG" ]; then | |
| HAS_CHANGES=true | |
| fi | |
| fi | |
| # Also check docs tag | |
| if [ "$HAS_CHANGES" = "false" ]; then | |
| DOCS_VERSION=$(node -p "require('./docs/package.json').version") | |
| if ! git rev-parse "docs@${DOCS_VERSION}" >/dev/null 2>&1; then | |
| HAS_CHANGES=true | |
| fi | |
| fi | |
| # Also check agent-plugins tag | |
| if [ "$HAS_CHANGES" = "false" ]; then | |
| PLUGINS_VERSION=$(node -p "require('./skills/package.json').version") | |
| if ! git rev-parse "b2c-agent-plugins@${PLUGINS_VERSION}" >/dev/null 2>&1; then | |
| HAS_CHANGES=true | |
| fi | |
| fi | |
| if [ "$HAS_CHANGES" = "false" ]; then | |
| echo "skip=true" >> $GITHUB_OUTPUT | |
| echo "::notice::All package versions match npm — nothing to publish" | |
| else | |
| echo "skip=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Setup pnpm | |
| if: steps.release-type.outputs.type == 'nightly' || (steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true') | |
| uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5 | |
| - name: Setup Node.js | |
| if: steps.release-type.outputs.type == 'nightly' || (steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true') | |
| uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 | |
| with: | |
| node-version: '22.22.1' | |
| cache: 'pnpm' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Upgrade npm for trusted publishing | |
| if: steps.release-type.outputs.type == 'nightly' || (steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true') | |
| run: npm install -g npm@latest | |
| - name: Install dependencies | |
| if: steps.release-type.outputs.type == 'nightly' || (steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true') | |
| run: pnpm install --frozen-lockfile | |
| - name: Determine packages to publish | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' | |
| id: packages | |
| run: | | |
| check_package() { | |
| local pkg_name=$1 | |
| local pkg_path=$2 | |
| local output_key=$3 | |
| LOCAL_VERSION=$(node -p "require('./${pkg_path}/package.json').version") | |
| NPM_VERSION=$(npm view "$pkg_name" version 2>/dev/null || echo "0.0.0") | |
| echo "${pkg_name}: local=${LOCAL_VERSION} npm=${NPM_VERSION}" | |
| if [ "$LOCAL_VERSION" != "$NPM_VERSION" ]; then | |
| echo "publish_${output_key}=true" >> $GITHUB_OUTPUT | |
| echo "version_${output_key}=${LOCAL_VERSION}" >> $GITHUB_OUTPUT | |
| # Determine appropriate npm dist-tag via semver comparison | |
| IS_NEWER=$(node -e " | |
| const [a,b,c] = '${LOCAL_VERSION}'.split('.').map(Number); | |
| const [x,y,z] = '${NPM_VERSION}'.split('.').map(Number); | |
| console.log(a>x||(a===x&&(b>y||(b===y&&c>z)))); | |
| ") | |
| if [ "$IS_NEWER" = "true" ]; then | |
| echo "tag_${output_key}=latest" >> $GITHUB_OUTPUT | |
| else | |
| MINOR=$(echo "$LOCAL_VERSION" | sed 's/\.[0-9]*$//') | |
| echo "tag_${output_key}=release-${MINOR}" >> $GITHUB_OUTPUT | |
| fi | |
| else | |
| echo "publish_${output_key}=false" >> $GITHUB_OUTPUT | |
| fi | |
| } | |
| check_package "@salesforce/b2c-tooling-sdk" "packages/b2c-tooling-sdk" "sdk" | |
| check_package "@salesforce/b2c-cli" "packages/b2c-cli" "cli" | |
| check_package "@salesforce/b2c-dx-mcp" "packages/b2c-dx-mcp" "mcp" | |
| check_package "@salesforce/mrt-utilities" "packages/mrt-utilities" "mrt" | |
| # VS Code extension — compare against git tags (not npm) | |
| LOCAL_VSX_VERSION=$(node -p "require('./packages/b2c-vs-extension/package.json').version") | |
| LAST_VSX_TAG=$(git tag -l "b2c-vs-extension@*" --sort=-v:refname | grep -v '@latest$' | head -1 | sed 's/b2c-vs-extension@//') | |
| echo "b2c-vs-extension: local=${LOCAL_VSX_VERSION} tag=${LAST_VSX_TAG:-none}" | |
| if [ "$LOCAL_VSX_VERSION" != "$LAST_VSX_TAG" ]; then | |
| echo "publish_vsx=true" >> $GITHUB_OUTPUT | |
| echo "version_vsx=${LOCAL_VSX_VERSION}" >> $GITHUB_OUTPUT | |
| else | |
| echo "publish_vsx=false" >> $GITHUB_OUTPUT | |
| fi | |
| # Check if docs version changed (private package — not published to npm, uses git tag) | |
| DOCS_VERSION=$(node -p "require('./docs/package.json').version") | |
| if git rev-parse "docs@${DOCS_VERSION}" >/dev/null 2>&1; then | |
| echo "publish_docs=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "publish_docs=true" >> $GITHUB_OUTPUT | |
| echo "version_docs=${DOCS_VERSION}" >> $GITHUB_OUTPUT | |
| fi | |
| echo "@salesforce/b2c-docs: version=${DOCS_VERSION}" | |
| # Check if agent-plugins version changed (private package — uses git tag) | |
| PLUGINS_VERSION=$(node -p "require('./skills/package.json').version") | |
| if git rev-parse "b2c-agent-plugins@${PLUGINS_VERSION}" >/dev/null 2>&1; then | |
| echo "publish_plugins=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "publish_plugins=true" >> $GITHUB_OUTPUT | |
| echo "version_plugins=${PLUGINS_VERSION}" >> $GITHUB_OUTPUT | |
| fi | |
| echo "@salesforce/b2c-agent-plugins: version=${PLUGINS_VERSION}" | |
| - name: Create snapshot versions | |
| if: steps.release-type.outputs.type == 'nightly' | |
| run: | | |
| SNAPSHOT="0.0.0-nightly.$(date +%Y%m%d%H%M%S)" | |
| for pkg in packages/b2c-tooling-sdk packages/b2c-cli packages/b2c-dx-mcp packages/mrt-utilities; do | |
| node -e " | |
| const fs = require('fs'); | |
| const path = '$pkg/package.json'; | |
| const pkg = JSON.parse(fs.readFileSync(path)); | |
| pkg.version = '$SNAPSHOT'; | |
| fs.writeFileSync(path, JSON.stringify(pkg, null, 2) + '\n'); | |
| " | |
| done | |
| echo "Set snapshot version: $SNAPSHOT" | |
| - name: Build packages | |
| if: steps.release-type.outputs.type == 'nightly' || (steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true') | |
| run: pnpm run build | |
| - name: Run tests | |
| if: steps.release-type.outputs.type == 'nightly' || (steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true') | |
| run: pnpm --filter '!b2c-vs-extension' run test | |
| - name: Publish SDK to npm | |
| if: steps.release-type.outputs.type == 'nightly' || steps.packages.outputs.publish_sdk == 'true' | |
| id: publish-sdk | |
| continue-on-error: true | |
| run: >- | |
| pnpm --filter @salesforce/b2c-tooling-sdk publish --provenance --no-git-checks | |
| --tag ${{ steps.release-type.outputs.type == 'nightly' && 'nightly' || steps.packages.outputs.tag_sdk }} | |
| - name: Publish CLI to npm | |
| if: steps.release-type.outputs.type == 'nightly' || steps.packages.outputs.publish_cli == 'true' | |
| id: publish-cli | |
| continue-on-error: true | |
| run: >- | |
| pnpm --filter @salesforce/b2c-cli publish --provenance --no-git-checks | |
| --tag ${{ steps.release-type.outputs.type == 'nightly' && 'nightly' || steps.packages.outputs.tag_cli }} | |
| - name: Publish MCP to npm | |
| if: steps.release-type.outputs.type == 'nightly' || steps.packages.outputs.publish_mcp == 'true' | |
| id: publish-mcp | |
| continue-on-error: true | |
| run: >- | |
| pnpm --filter @salesforce/b2c-dx-mcp publish --provenance --no-git-checks | |
| --tag ${{ steps.release-type.outputs.type == 'nightly' && 'nightly' || steps.packages.outputs.tag_mcp }} | |
| - name: Publish MRT Utilities to npm | |
| if: steps.release-type.outputs.type == 'nightly' || steps.packages.outputs.publish_mrt == 'true' | |
| id: publish-mrt | |
| continue-on-error: true | |
| run: >- | |
| pnpm --filter @salesforce/mrt-utilities publish --provenance --no-git-checks | |
| --tag ${{ steps.release-type.outputs.type == 'nightly' && 'nightly' || steps.packages.outputs.tag_mrt }} | |
| - name: Package VS Code extension | |
| if: steps.release-type.outputs.type == 'stable' && steps.packages.outputs.publish_vsx == 'true' | |
| working-directory: packages/b2c-vs-extension | |
| run: pnpm run package | |
| - name: Create git tags | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| TAGS_CREATED="" | |
| if [[ "${{ steps.packages.outputs.publish_sdk }}" == "true" ]]; then | |
| TAG="@salesforce/b2c-tooling-sdk@${{ steps.packages.outputs.version_sdk }}" | |
| git tag "$TAG" | |
| TAGS_CREATED="$TAGS_CREATED $TAG" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_cli }}" == "true" ]]; then | |
| TAG="@salesforce/b2c-cli@${{ steps.packages.outputs.version_cli }}" | |
| git tag "$TAG" | |
| TAGS_CREATED="$TAGS_CREATED $TAG" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_mcp }}" == "true" ]]; then | |
| TAG="@salesforce/b2c-dx-mcp@${{ steps.packages.outputs.version_mcp }}" | |
| git tag "$TAG" | |
| TAGS_CREATED="$TAGS_CREATED $TAG" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_mrt }}" == "true" ]]; then | |
| TAG="@salesforce/mrt-utilities@${{ steps.packages.outputs.version_mrt }}" | |
| git tag "$TAG" | |
| TAGS_CREATED="$TAGS_CREATED $TAG" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_vsx }}" == "true" ]]; then | |
| TAG="b2c-vs-extension@${{ steps.packages.outputs.version_vsx }}" | |
| git tag "$TAG" | |
| TAGS_CREATED="$TAGS_CREATED $TAG" | |
| fi | |
| if [ -n "$TAGS_CREATED" ]; then | |
| git push origin $TAGS_CREATED | |
| echo "Created tags:$TAGS_CREATED" | |
| else | |
| echo "No tags to create" | |
| fi | |
| - name: Update b2c-vs-extension@latest tag | |
| if: steps.release-type.outputs.type == 'stable' && steps.packages.outputs.publish_vsx == 'true' | |
| run: | | |
| git tag -f b2c-vs-extension@latest | |
| git push origin b2c-vs-extension@latest --force | |
| echo "Updated b2c-vs-extension@latest tag to $(git rev-parse HEAD)" | |
| - name: Update v1 Actions tag | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' | |
| run: | | |
| git tag -f v1 | |
| git push origin v1 --force | |
| echo "Updated v1 tag to $(git rev-parse HEAD)" | |
| - name: Create docs tag if version changed | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' && steps.packages.outputs.publish_docs == 'true' | |
| run: | | |
| DOCS_TAG="docs@${{ steps.packages.outputs.version_docs }}" | |
| git tag "$DOCS_TAG" | |
| git push origin "$DOCS_TAG" | |
| echo "Created docs tag: $DOCS_TAG" | |
| - name: Extract changelogs for release | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' | |
| run: | | |
| # Function to extract the latest version section from a changelog | |
| extract_latest() { | |
| awk ' | |
| /^## / { if (found) exit; found=1; next } | |
| found { print } | |
| ' "$1" | |
| } | |
| # Build combined release notes for published packages | |
| { | |
| if [[ "${{ steps.packages.outputs.publish_cli }}" == "true" ]]; then | |
| echo "## @salesforce/b2c-cli@${{ steps.packages.outputs.version_cli }}" | |
| echo "" | |
| extract_latest packages/b2c-cli/CHANGELOG.md | |
| echo "" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_mcp }}" == "true" ]]; then | |
| echo "## @salesforce/b2c-dx-mcp@${{ steps.packages.outputs.version_mcp }}" | |
| echo "" | |
| extract_latest packages/b2c-dx-mcp/CHANGELOG.md | |
| echo "" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_sdk }}" == "true" ]]; then | |
| echo "## @salesforce/b2c-tooling-sdk@${{ steps.packages.outputs.version_sdk }}" | |
| echo "" | |
| extract_latest packages/b2c-tooling-sdk/CHANGELOG.md | |
| echo "" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_mrt }}" == "true" ]]; then | |
| echo "## @salesforce/mrt-utilities@${{ steps.packages.outputs.version_mrt }}" | |
| echo "" | |
| extract_latest packages/mrt-utilities/CHANGELOG.md | |
| echo "" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_vsx }}" == "true" ]]; then | |
| echo "## b2c-vs-extension@${{ steps.packages.outputs.version_vsx }}" | |
| echo "" | |
| extract_latest packages/b2c-vs-extension/CHANGELOG.md | |
| echo "" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_docs }}" == "true" && -f docs/CHANGELOG.md ]]; then | |
| echo "## Documentation" | |
| echo "" | |
| extract_latest docs/CHANGELOG.md | |
| echo "" | |
| fi | |
| if [[ "${{ steps.packages.outputs.publish_plugins }}" == "true" && -f skills/CHANGELOG.md ]]; then | |
| echo "## Agent Skills Plugins" | |
| echo "" | |
| extract_latest skills/CHANGELOG.md | |
| echo "" | |
| fi | |
| } > /tmp/release-notes.md | |
| - name: Create GitHub Release | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' | |
| run: | | |
| # Determine the release tag — prefer CLI as the user-facing product | |
| if [[ "${{ steps.packages.outputs.publish_cli }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-cli@${{ steps.packages.outputs.version_cli }}" | |
| elif [[ "${{ steps.packages.outputs.publish_sdk }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-tooling-sdk@${{ steps.packages.outputs.version_sdk }}" | |
| elif [[ "${{ steps.packages.outputs.publish_mcp }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-dx-mcp@${{ steps.packages.outputs.version_mcp }}" | |
| elif [[ "${{ steps.packages.outputs.publish_mrt }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/mrt-utilities@${{ steps.packages.outputs.version_mrt }}" | |
| elif [[ "${{ steps.packages.outputs.publish_vsx }}" == "true" ]]; then | |
| RELEASE_TAG="b2c-vs-extension@${{ steps.packages.outputs.version_vsx }}" | |
| elif [[ "${{ steps.packages.outputs.publish_docs }}" == "true" ]]; then | |
| RELEASE_TAG="docs@${{ steps.packages.outputs.version_docs }}" | |
| elif [[ "${{ steps.packages.outputs.publish_plugins }}" == "true" ]]; then | |
| RELEASE_TAG="b2c-agent-plugins@${{ steps.packages.outputs.version_plugins }}" | |
| else | |
| echo "No packages published, skipping release" | |
| exit 0 | |
| fi | |
| gh release create "$RELEASE_TAG" --notes-file /tmp/release-notes.md | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Package skills artifacts | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' && steps.packages.outputs.publish_plugins == 'true' | |
| run: | | |
| # Create b2c-skills.zip containing skills/b2c/skills/ | |
| cd skills/b2c && zip -r ../../b2c-skills.zip skills/ | |
| cd ../.. | |
| # Create b2c-cli-skills.zip containing skills/b2c-cli/skills/ | |
| cd skills/b2c-cli && zip -r ../../b2c-cli-skills.zip skills/ | |
| cd ../.. | |
| echo "Created skills artifacts:" | |
| ls -la *.zip | |
| - name: Upload skills to release | |
| if: steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' && steps.packages.outputs.publish_plugins == 'true' | |
| run: | | |
| # Determine the release tag (same priority as Create GitHub Release) | |
| if [[ "${{ steps.packages.outputs.publish_cli }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-cli@${{ steps.packages.outputs.version_cli }}" | |
| elif [[ "${{ steps.packages.outputs.publish_sdk }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-tooling-sdk@${{ steps.packages.outputs.version_sdk }}" | |
| elif [[ "${{ steps.packages.outputs.publish_mcp }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-dx-mcp@${{ steps.packages.outputs.version_mcp }}" | |
| elif [[ "${{ steps.packages.outputs.publish_mrt }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/mrt-utilities@${{ steps.packages.outputs.version_mrt }}" | |
| elif [[ "${{ steps.packages.outputs.publish_vsx }}" == "true" ]]; then | |
| RELEASE_TAG="b2c-vs-extension@${{ steps.packages.outputs.version_vsx }}" | |
| elif [[ "${{ steps.packages.outputs.publish_docs }}" == "true" ]]; then | |
| RELEASE_TAG="docs@${{ steps.packages.outputs.version_docs }}" | |
| else | |
| RELEASE_TAG="b2c-agent-plugins@${{ steps.packages.outputs.version_plugins }}" | |
| fi | |
| gh release upload "$RELEASE_TAG" b2c-skills.zip b2c-cli-skills.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload VS Code extension to release | |
| if: steps.release-type.outputs.type == 'stable' && steps.packages.outputs.publish_vsx == 'true' | |
| run: | | |
| # Determine the release tag (same logic as Create GitHub Release) | |
| if [[ "${{ steps.packages.outputs.publish_cli }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-cli@${{ steps.packages.outputs.version_cli }}" | |
| elif [[ "${{ steps.packages.outputs.publish_sdk }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-tooling-sdk@${{ steps.packages.outputs.version_sdk }}" | |
| elif [[ "${{ steps.packages.outputs.publish_mcp }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/b2c-dx-mcp@${{ steps.packages.outputs.version_mcp }}" | |
| elif [[ "${{ steps.packages.outputs.publish_mrt }}" == "true" ]]; then | |
| RELEASE_TAG="@salesforce/mrt-utilities@${{ steps.packages.outputs.version_mrt }}" | |
| elif [[ "${{ steps.packages.outputs.publish_vsx }}" == "true" ]]; then | |
| RELEASE_TAG="b2c-vs-extension@${{ steps.packages.outputs.version_vsx }}" | |
| else | |
| echo "No release to upload to" | |
| exit 0 | |
| fi | |
| gh release upload "$RELEASE_TAG" packages/b2c-vs-extension/*.vsix | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create VS Code extension release | |
| if: >- | |
| steps.release-type.outputs.type == 'stable' | |
| && steps.packages.outputs.publish_vsx == 'true' | |
| run: | | |
| VSX_TAG="b2c-vs-extension@${{ steps.packages.outputs.version_vsx }}" | |
| # Create a dedicated release for the extension (not latest — main releases own that) | |
| # Use --clobber on upload in case a previous run partially completed | |
| if gh release view "$VSX_TAG" >/dev/null 2>&1; then | |
| echo "Release $VSX_TAG already exists, uploading VSIX to it" | |
| gh release upload "$VSX_TAG" packages/b2c-vs-extension/*.vsix --clobber | |
| else | |
| gh release create "$VSX_TAG" \ | |
| --title "VS Code Extension ${{ steps.packages.outputs.version_vsx }}" \ | |
| --latest=false \ | |
| --notes "$(cat <<'NOTES' | |
| ## B2C DX VS Code Extension v${{ steps.packages.outputs.version_vsx }} | |
| Download the `.vsix` file below and install via: | |
| ``` | |
| code --install-extension b2c-vs-extension-${{ steps.packages.outputs.version_vsx }}.vsix | |
| ``` | |
| Or in VS Code: Extensions → ⋯ → Install from VSIX... | |
| NOTES | |
| )" | |
| # Upload the VSIX to the dedicated release | |
| gh release upload "$VSX_TAG" packages/b2c-vs-extension/*.vsix | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Trigger documentation deployment | |
| if: >- | |
| steps.release-type.outputs.type == 'stable' && steps.changesets.outputs.skip != 'true' && steps.quick-check.outputs.skip != 'true' | |
| && (steps.packages.outputs.tag_cli == 'latest' || steps.packages.outputs.tag_sdk == 'latest' || steps.packages.outputs.tag_mcp == 'latest' || steps.packages.outputs.publish_docs == 'true') | |
| run: gh workflow run deploy-docs.yml | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create PR to merge version bumps back to main | |
| if: github.event_name == 'workflow_run' | |
| run: | | |
| if [[ "${{ steps.packages.outputs.publish_sdk }}" == "true" ]] || \ | |
| [[ "${{ steps.packages.outputs.publish_cli }}" == "true" ]] || \ | |
| [[ "${{ steps.packages.outputs.publish_mcp }}" == "true" ]] || \ | |
| [[ "${{ steps.packages.outputs.publish_mrt }}" == "true" ]] || \ | |
| [[ "${{ steps.packages.outputs.publish_docs }}" == "true" ]]; then | |
| BRANCH="${{ github.event.workflow_run.head_branch }}" | |
| gh pr create --base main --head "$BRANCH" \ | |
| --title "Merge version bumps from ${BRANCH}" \ | |
| --body "$(cat <<'EOF' | |
| Auto-created after release branch publish from `'"${BRANCH}"'`. | |
| Merges version bump commits back to main to prevent version collisions on the next regular release. | |
| **Review checklist:** | |
| - [ ] Version bumps in package.json files look correct | |
| - [ ] CHANGELOG entries are accurate | |
| - [ ] No merge conflicts with pending changesets on main | |
| EOF | |
| )" || echo "::warning::PR already exists or could not be created" | |
| fi | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Fail if any publish failed | |
| if: always() && (steps.publish-sdk.outcome == 'failure' || steps.publish-cli.outcome == 'failure' || steps.publish-mcp.outcome == 'failure' || steps.publish-mrt.outcome == 'failure') | |
| run: | | |
| echo "::error::One or more npm publishes failed:" | |
| [[ "${{ steps.publish-sdk.outcome }}" == "failure" ]] && echo " - SDK" | |
| [[ "${{ steps.publish-cli.outcome }}" == "failure" ]] && echo " - CLI" | |
| [[ "${{ steps.publish-mcp.outcome }}" == "failure" ]] && echo " - MCP" | |
| [[ "${{ steps.publish-mrt.outcome }}" == "failure" ]] && echo " - MRT" | |
| exit 1 |