Skip to content

Publish to npm

Publish to npm #55

Workflow file for this run

name: Publish to npm
on:
schedule:
- cron: '0 2 * * 1-5' # Weekdays at 2 AM UTC (Mon-Fri)
workflow_dispatch:
inputs:
release_type:
description: 'Release type'
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
permissions:
contents: write # For creating GitHub releases and tags
id-token: write # Required for npm OIDC trusted publishers
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Determine release type
id: release-type
run: |
if [[ "${{ github.event.inputs.release_type }}" == "stable" ]]; then
echo "type=stable" >> $GITHUB_OUTPUT
echo "tag=latest" >> $GITHUB_OUTPUT
else
echo "type=nightly" >> $GITHUB_OUTPUT
echo "tag=nightly" >> $GITHUB_OUTPUT
fi
- name: Setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
- name: Upgrade npm for trusted publishing
run: npm install -g npm@latest
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Determine packages to publish
if: steps.release-type.outputs.type == 'stable'
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
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"
- 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; 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
run: pnpm run build
- name: Run tests
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'
run: pnpm --filter @salesforce/b2c-tooling-sdk publish --provenance --no-git-checks --tag ${{ steps.release-type.outputs.tag }}
- name: Publish CLI to npm
if: steps.release-type.outputs.type == 'nightly' || steps.packages.outputs.publish_cli == 'true'
run: pnpm --filter @salesforce/b2c-cli publish --provenance --no-git-checks --tag ${{ steps.release-type.outputs.tag }}
- name: Publish MCP to npm
if: steps.release-type.outputs.type == 'nightly' || steps.packages.outputs.publish_mcp == 'true'
run: pnpm --filter @salesforce/b2c-dx-mcp publish --provenance --no-git-checks --tag ${{ steps.release-type.outputs.tag }}
- name: Create git tags
if: steps.release-type.outputs.type == 'stable'
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 [ -n "$TAGS_CREATED" ]; then
git push origin $TAGS_CREATED
echo "Created tags:$TAGS_CREATED"
else
echo "No tags to create"
fi
- name: Extract changelogs for release
if: steps.release-type.outputs.type == 'stable'
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
} > /tmp/release-notes.md
- name: Create GitHub Release
if: steps.release-type.outputs.type == 'stable'
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 }}"
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'
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'
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 }}"
else
echo "No release to upload to"
exit 0
fi
gh release upload "$RELEASE_TAG" b2c-skills.zip b2c-cli-skills.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}