Skip to content

Commit d0140a8

Browse files
author
Marvin Zhang
committed
chore: update publish workflow for improved package publishing logic and remove deprecated release workflow
1 parent 7c209c0 commit d0140a8

File tree

3 files changed

+157
-297
lines changed

3 files changed

+157
-297
lines changed

.github/workflows/publish.yml

Lines changed: 156 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,47 @@
1-
name: Publish to NPM
1+
name: Auto Publish to NPM
22

33
on:
44
push:
5-
tags:
6-
- 'v*'
5+
branches: [main, develop]
6+
paths:
7+
- 'packages/*/package.json'
8+
- 'packages/*/src/**'
9+
- 'packages/*/build/**'
710
workflow_dispatch:
811
inputs:
9-
version:
10-
description: 'Version to publish (patch, minor, major, or specific version like 1.2.3)'
11-
required: true
12-
default: 'patch'
13-
type: choice
14-
options:
15-
- patch
16-
- minor
17-
- major
12+
force_publish:
13+
description: 'Force publish packages even if versions match'
14+
required: false
15+
default: false
16+
type: boolean
1817
packages:
19-
description: 'Packages to publish (comma-separated: mcp,types or leave empty for all)'
18+
description: 'Specific packages to check (comma-separated: mcp,core,ai,cli or leave empty for all)'
2019
required: false
2120
type: string
2221

2322
jobs:
24-
publish:
23+
check-and-publish:
2524
runs-on: ubuntu-latest
2625
permissions:
27-
contents: write
26+
contents: read
2827
id-token: write
2928

3029
steps:
3130
- name: Checkout code
3231
uses: actions/checkout@v4
3332
with:
3433
fetch-depth: 0
35-
token: ${{ secrets.GITHUB_TOKEN }}
3634

3735
- name: Setup Node.js
3836
uses: actions/setup-node@v4
3937
with:
40-
node-version: '18'
38+
node-version: '20'
4139
registry-url: 'https://registry.npmjs.org'
4240

4341
- name: Setup pnpm
4442
uses: pnpm/action-setup@v4
4543
with:
46-
version: 10.12.1
44+
version: 10.13.1
4745
run_install: false
4846

4947
- name: Get pnpm store directory
@@ -66,116 +64,156 @@ jobs:
6664
run: pnpm build
6765

6866
- name: Run tests
69-
run: pnpm test
70-
71-
- name: Configure git
72-
run: |
73-
git config --local user.email "[email protected]"
74-
git config --local user.name "GitHub Action"
67+
run: pnpm test && pnpm test:packages
7568

76-
- name: Determine version bump
77-
id: version
69+
- name: Check versions and determine what to publish
70+
id: check_versions
71+
env:
72+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
7873
run: |
79-
if [ "${{ github.event_name }}" == "push" ] && [[ "${{ github.ref }}" == refs/tags/* ]]; then
80-
VERSION="${{ github.ref_name }}"
81-
VERSION="${VERSION#v}" # Remove 'v' prefix
82-
echo "version=$VERSION" >> $GITHUB_OUTPUT
83-
echo "bump=false" >> $GITHUB_OUTPUT
84-
else
85-
VERSION="${{ github.event.inputs.version }}"
86-
echo "version=$VERSION" >> $GITHUB_OUTPUT
87-
echo "bump=true" >> $GITHUB_OUTPUT
74+
PACKAGES_TO_PUBLISH=""
75+
FORCE_PUBLISH="${{ github.event.inputs.force_publish }}"
76+
SPECIFIED_PACKAGES="${{ github.event.inputs.packages }}"
77+
78+
# Define all publishable packages
79+
declare -A PACKAGE_MAP=(
80+
["mcp"]="packages/mcp"
81+
["core"]="packages/core"
82+
["ai"]="packages/ai"
83+
["cli"]="packages/cli"
84+
)
85+
86+
# If specific packages specified, filter to those
87+
if [ -n "$SPECIFIED_PACKAGES" ]; then
88+
IFS=',' read -ra SPECIFIED_ARRAY <<< "$SPECIFIED_PACKAGES"
89+
declare -A FILTERED_MAP
90+
for pkg in "${SPECIFIED_ARRAY[@]}"; do
91+
pkg=$(echo "$pkg" | xargs) # trim whitespace
92+
if [[ -n "${PACKAGE_MAP[$pkg]}" ]]; then
93+
FILTERED_MAP[$pkg]="${PACKAGE_MAP[$pkg]}"
94+
fi
95+
done
96+
PACKAGE_MAP=()
97+
for key in "${!FILTERED_MAP[@]}"; do
98+
PACKAGE_MAP[$key]="${FILTERED_MAP[$key]}"
99+
done
88100
fi
89-
90-
- name: Determine packages to publish
91-
id: packages
92-
run: |
93-
if [ -n "${{ github.event.inputs.packages }}" ]; then
94-
PACKAGES="${{ github.event.inputs.packages }}"
95-
else
96-
PACKAGES="mcp,types"
97-
fi
98-
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
99-
100-
- name: Version bump packages
101-
if: steps.version.outputs.bump == 'true'
102-
run: |
103-
IFS=',' read -ra PACKAGE_ARRAY <<< "${{ steps.packages.outputs.packages }}"
104-
for pkg in "${PACKAGE_ARRAY[@]}"; do
105-
pkg=$(echo "$pkg" | xargs) # trim whitespace
106-
if [ "$pkg" == "mcp" ]; then
107-
cd packages/mcp
108-
npm version ${{ steps.version.outputs.version }} --no-git-tag-version
109-
cd ../..
110-
elif [ "$pkg" == "types" ]; then
111-
cd packages/types
112-
npm version ${{ steps.version.outputs.version }} --no-git-tag-version
113-
cd ../..
114-
fi
115-
done
116-
117-
- name: Set specific version for packages
118-
if: steps.version.outputs.bump == 'false'
119-
run: |
120-
IFS=',' read -ra PACKAGE_ARRAY <<< "${{ steps.packages.outputs.packages }}"
121-
for pkg in "${PACKAGE_ARRAY[@]}"; do
122-
pkg=$(echo "$pkg" | xargs) # trim whitespace
123-
if [ "$pkg" == "mcp" ]; then
124-
cd packages/mcp
125-
npm version ${{ steps.version.outputs.version }} --no-git-tag-version --allow-same-version
126-
cd ../..
127-
elif [ "$pkg" == "types" ]; then
128-
cd packages/types
129-
npm version ${{ steps.version.outputs.version }} --no-git-tag-version --allow-same-version
130-
cd ../..
101+
102+
for pkg_key in "${!PACKAGE_MAP[@]}"; do
103+
pkg_dir="${PACKAGE_MAP[$pkg_key]}"
104+
105+
if [ -f "$pkg_dir/package.json" ]; then
106+
PKG_NAME=$(jq -r '.name' "$pkg_dir/package.json")
107+
LOCAL_VERSION=$(jq -r '.version' "$pkg_dir/package.json")
108+
109+
echo "Checking $PKG_NAME@$LOCAL_VERSION..."
110+
111+
# Check if package exists on npm and get published version
112+
NPM_VERSION=$(npm view "$PKG_NAME" version 2>/dev/null || echo "0.0.0")
113+
114+
echo "Local: $LOCAL_VERSION, NPM: $NPM_VERSION"
115+
116+
# Compare versions using node semver logic
117+
SHOULD_PUBLISH=$(node -e "
118+
const semver = require('semver');
119+
const local = '$LOCAL_VERSION';
120+
const npm = '$NPM_VERSION';
121+
const force = '$FORCE_PUBLISH' === 'true';
122+
123+
if (force) {
124+
console.log('true');
125+
} else if (npm === '0.0.0') {
126+
// Package doesn't exist on npm
127+
console.log('true');
128+
} else {
129+
// Check if local version is greater than npm version
130+
console.log(semver.gt(local, npm) ? 'true' : 'false');
131+
}
132+
")
133+
134+
if [ "$SHOULD_PUBLISH" = "true" ]; then
135+
echo "✅ Will publish $PKG_NAME@$LOCAL_VERSION (npm has $NPM_VERSION)"
136+
PACKAGES_TO_PUBLISH="$PACKAGES_TO_PUBLISH$pkg_key,"
137+
else
138+
echo "⏭️ Skipping $PKG_NAME@$LOCAL_VERSION (same as or older than npm version $NPM_VERSION)"
139+
fi
131140
fi
132141
done
133-
134-
- name: Rebuild after version update
135-
run: pnpm build
142+
143+
# Remove trailing comma
144+
PACKAGES_TO_PUBLISH=${PACKAGES_TO_PUBLISH%,}
145+
146+
echo "packages_to_publish=$PACKAGES_TO_PUBLISH" >> $GITHUB_OUTPUT
147+
148+
if [ -z "$PACKAGES_TO_PUBLISH" ]; then
149+
echo "has_packages_to_publish=false" >> $GITHUB_OUTPUT
150+
echo "No packages need to be published."
151+
else
152+
echo "has_packages_to_publish=true" >> $GITHUB_OUTPUT
153+
echo "Packages to publish: $PACKAGES_TO_PUBLISH"
154+
fi
136155
137156
- name: Publish packages
157+
id: publish
158+
if: steps.check_versions.outputs.has_packages_to_publish == 'true'
138159
env:
139-
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
160+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
140161
run: |
141-
IFS=',' read -ra PACKAGE_ARRAY <<< "${{ steps.packages.outputs.packages }}"
162+
PACKAGES="${{ steps.check_versions.outputs.packages_to_publish }}"
163+
IFS=',' read -ra PACKAGE_ARRAY <<< "$PACKAGES"
164+
165+
PUBLISHED_PACKAGES=""
166+
142167
for pkg in "${PACKAGE_ARRAY[@]}"; do
143-
pkg=$(echo "$pkg" | xargs) # trim whitespace
144-
if [ "$pkg" == "mcp" ]; then
145-
echo "Publishing @codervisor/devlog-mcp..."
146-
cd packages/mcp
147-
npm publish --access public
148-
cd ../..
149-
elif [ "$pkg" == "types" ]; then
150-
echo "Publishing @codervisor/devlog-types..."
151-
cd packages/types
152-
npm publish --access public
153-
cd ../..
154-
fi
168+
case $pkg in
169+
"mcp")
170+
echo "Publishing @codervisor/devlog-mcp..."
171+
cd packages/mcp
172+
npm publish --access public
173+
PUBLISHED_PACKAGES="$PUBLISHED_PACKAGES@codervisor/devlog-mcp@$(jq -r '.version' package.json) "
174+
cd ../..
175+
;;
176+
"core")
177+
echo "Publishing @codervisor/devlog-core..."
178+
cd packages/core
179+
npm publish --access public
180+
PUBLISHED_PACKAGES="$PUBLISHED_PACKAGES@codervisor/devlog-core@$(jq -r '.version' package.json) "
181+
cd ../..
182+
;;
183+
"ai")
184+
echo "Publishing @codervisor/devlog-ai..."
185+
cd packages/ai
186+
npm publish --access public
187+
PUBLISHED_PACKAGES="$PUBLISHED_PACKAGES@codervisor/devlog-ai@$(jq -r '.version' package.json) "
188+
cd ../..
189+
;;
190+
"cli")
191+
echo "Publishing @codervisor/devlog-cli..."
192+
cd packages/cli
193+
npm publish --access public
194+
PUBLISHED_PACKAGES="$PUBLISHED_PACKAGES@codervisor/devlog-cli@$(jq -r '.version' package.json) "
195+
cd ../..
196+
;;
197+
esac
155198
done
199+
200+
echo "published_packages=$PUBLISHED_PACKAGES" >> $GITHUB_OUTPUT
201+
echo "Successfully published: $PUBLISHED_PACKAGES"
156202
157-
- name: Commit version changes
158-
if: steps.version.outputs.bump == 'true'
203+
- name: Create summary
204+
if: always()
159205
run: |
160-
git add .
161-
git commit -m "chore: bump version to ${{ steps.version.outputs.version }}" || echo "No changes to commit"
162-
git push origin main
163-
164-
- name: Create GitHub release
165-
if: steps.version.outputs.bump == 'true'
166-
uses: actions/create-release@v1
167-
env:
168-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
169-
with:
170-
tag_name: v${{ steps.version.outputs.version }}
171-
release_name: Release v${{ steps.version.outputs.version }}
172-
body: |
173-
## Changes
174-
175-
Published packages: ${{ steps.packages.outputs.packages }}
176-
177-
### Packages
178-
- @codervisor/devlog-mcp@${{ steps.version.outputs.version }}
179-
- @codervisor/devlog-types@${{ steps.version.outputs.version }}
180-
draft: false
181-
prerelease: false
206+
echo "## 📦 NPM Publish Results" >> $GITHUB_STEP_SUMMARY
207+
208+
if [ "${{ steps.check_versions.outputs.has_packages_to_publish }}" == "true" ]; then
209+
echo "### ✅ Successfully Published" >> $GITHUB_STEP_SUMMARY
210+
echo "${{ steps.publish.outputs.published_packages }}" >> $GITHUB_STEP_SUMMARY
211+
else
212+
echo "### ℹ️ No Packages to Publish" >> $GITHUB_STEP_SUMMARY
213+
echo "All package versions are up to date with npmjs.org" >> $GITHUB_STEP_SUMMARY
214+
fi
215+
216+
echo "" >> $GITHUB_STEP_SUMMARY
217+
echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
218+
echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
219+
echo "**Commit:** ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)