Skip to content

Publish latest builds #2

Publish latest builds

Publish latest builds #2

name: Publish latest builds
on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish (e.g., 1.2.3)'
required: true
type: string
permissions:
id-token: write
contents: write
jobs:
publish:
name: Publish latest builds
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: pnpm/action-setup@v4
with:
version: '10.30.3'
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Validate version input
run: |
if ! [[ "${{ github.event.inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Version must be in semantic version format (e.g., 1.2.3)"
exit 1
fi
- name: Update package versions
run: |
target_version="${{ github.event.inputs.version }}"
echo "Setting version to: $target_version"
for dir in packages/*; do
[ -f "$dir/package.json" ] || continue
echo "Updating $dir/package.json..."
node -e "
const fs = require('fs');
const path = './$dir/package.json';
const pkg = require(path);
pkg.version = '$target_version';
fs.writeFileSync(path, JSON.stringify(pkg, null, 2));
console.log('Updated ' + pkg.name + ' to version ' + pkg.version);
"
done
- name: Build packages
run: pnpm dlx turbo build --filter='./packages/*'
- name: Publish packages
run: |
PACKAGES=(
"commandkit:packages/commandkit"
"create-commandkit:packages/create-commandkit"
"@commandkit/redis:packages/redis"
"@commandkit/i18n:packages/i18n"
"@commandkit/devtools:packages/devtools"
"@commandkit/cache:packages/cache"
"@commandkit/analytics:packages/analytics"
"@commandkit/ai:packages/ai"
"@commandkit/queue:packages/queue"
"@commandkit/tasks:packages/tasks"
"@commandkit/workflow:packages/workflow"
)
for entry in "${PACKAGES[@]}"; do
IFS=":" read -r name path <<< "$entry"
echo "Publishing $name..."
VERSION=$(node -p "require('./$path/package.json').version")
if npm view "$name@$VERSION" version >/dev/null 2>&1; then
echo "📦 $name@$VERSION already exists on npm, skipping..."
else
if pnpm --filter="$name" publish --no-git-checks --access public; then
echo "✅ Published $name@$VERSION"
else
if npm view "$name@$VERSION" version >/dev/null 2>&1; then
echo "📦 $name@$VERSION was published by another process, skipping..."
else
echo "❌ Failed to publish $name@$VERSION"
exit 1
fi
fi
fi
done
- name: Generate changelog
id: changelog
run: |
VERSION="v${{ github.event.inputs.version }}"
# Find the previous version tag
PREV_TAG=$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1)
if [ -z "$PREV_TAG" ]; then
COMMIT_RANGE="HEAD"
echo "No previous tag found, using all commits"
else
COMMIT_RANGE="${PREV_TAG}..HEAD"
echo "Generating changelog from $PREV_TAG to HEAD"
fi
PACKAGES=(
"commandkit:packages/commandkit"
"create-commandkit:packages/create-commandkit"
"@commandkit/redis:packages/redis"
"@commandkit/i18n:packages/i18n"
"@commandkit/devtools:packages/devtools"
"@commandkit/cache:packages/cache"
"@commandkit/analytics:packages/analytics"
"@commandkit/ai:packages/ai"
"@commandkit/queue:packages/queue"
"@commandkit/tasks:packages/tasks"
"@commandkit/workflow:packages/workflow"
)
CHANGELOG=""
for entry in "${PACKAGES[@]}"; do
IFS=":" read -r name path <<< "$entry"
COMMITS=$(git log "$COMMIT_RANGE" --pretty=format:"%s|%h" -- "$path" 2>/dev/null || true)
[ -z "$COMMITS" ] && continue
FEATS=""
FIXES=""
CHORES=""
DOCS=""
REFACTORS=""
PERFS=""
TESTS=""
OTHERS=""
while IFS='|' read -r msg hash; do
line="- ${msg} (\`${hash}\`)"
case "$msg" in
feat:*|feat\(*) FEATS+=$'\n'"$line" ;;
fix:*|fix\(*) FIXES+=$'\n'"$line" ;;
chore:*|chore\(*) CHORES+=$'\n'"$line" ;;
docs:*|docs\(*) DOCS+=$'\n'"$line" ;;
refactor:*|refactor\(*) REFACTORS+=$'\n'"$line" ;;
perf:*|perf\(*) PERFS+=$'\n'"$line" ;;
test:*|test\(*|tests:*|tests\(*) TESTS+=$'\n'"$line" ;;
*) OTHERS+=$'\n'"$line" ;;
esac
done <<< "$COMMITS"
PKG_SECTION="## ${name}"$'\n'
HAS_CONTENT=false
for category_label in \
"🚀 Features|$FEATS" \
"🐛 Bug Fixes|$FIXES" \
"🧹 Chores|$CHORES" \
"📖 Documentation|$DOCS" \
"♻️ Refactors|$REFACTORS" \
"⚡ Performance|$PERFS" \
"🧪 Tests|$TESTS" \
"📦 Other Changes|$OTHERS"; do
IFS='|' read -r label content <<< "$category_label"
if [ -n "$content" ]; then
PKG_SECTION+=$'\n'"### ${label}"$'\n'"${content}"$'\n'
HAS_CONTENT=true
fi
done
if [ "$HAS_CONTENT" = true ]; then
CHANGELOG+=$'\n'"${PKG_SECTION}"$'\n'
fi
done
if [ -z "$CHANGELOG" ]; then
CHANGELOG="No package changes detected since the last release."
fi
# Write to file to avoid shell escaping issues
echo "$CHANGELOG" > /tmp/changelog.md
- name: Create GitHub draft release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ github.event.inputs.version }}
name: v${{ github.event.inputs.version }}
body_path: /tmp/changelog.md
draft: true
generate_release_notes: false