@burgan-tech/vnext-workflow-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build-and-publish.yml +702 -0
- package/.github/workflows/check-sonar.yml +69 -0
- package/README.md +382 -0
- package/bin/workflow.js +70 -0
- package/package.json +44 -0
- package/src/commands/check.js +74 -0
- package/src/commands/config.js +31 -0
- package/src/commands/csx.js +85 -0
- package/src/commands/reset.js +161 -0
- package/src/commands/sync.js +189 -0
- package/src/commands/update.js +203 -0
- package/src/lib/api.js +72 -0
- package/src/lib/config.js +29 -0
- package/src/lib/csx.js +191 -0
- package/src/lib/db.js +122 -0
- package/src/lib/discover.js +65 -0
- package/src/lib/workflow.js +162 -0
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
name: Build and Publish to NPM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- 'release-v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version_override:
|
|
10
|
+
description: 'Override version (e.g., 1.0.6). Leave empty to auto-calculate from branch.'
|
|
11
|
+
required: false
|
|
12
|
+
type: string
|
|
13
|
+
force_publish:
|
|
14
|
+
description: 'Force publish package even if it already exists'
|
|
15
|
+
required: false
|
|
16
|
+
default: false
|
|
17
|
+
type: boolean
|
|
18
|
+
registry_target:
|
|
19
|
+
description: 'Target registry for publishing'
|
|
20
|
+
required: false
|
|
21
|
+
default: 'npmjs'
|
|
22
|
+
type: choice
|
|
23
|
+
options:
|
|
24
|
+
- 'npmjs'
|
|
25
|
+
- 'github'
|
|
26
|
+
- 'both'
|
|
27
|
+
|
|
28
|
+
permissions:
|
|
29
|
+
contents: write
|
|
30
|
+
packages: write
|
|
31
|
+
|
|
32
|
+
jobs:
|
|
33
|
+
build-and-publish:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
|
|
36
|
+
outputs:
|
|
37
|
+
version: ${{ steps.version.outputs.version }}
|
|
38
|
+
published: ${{ steps.publish.outputs.published }}
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- name: Checkout code
|
|
42
|
+
uses: actions/checkout@v4
|
|
43
|
+
with:
|
|
44
|
+
fetch-depth: 0 # Fetch all history for version calculation
|
|
45
|
+
|
|
46
|
+
- name: Setup Node.js
|
|
47
|
+
uses: actions/setup-node@v4
|
|
48
|
+
with:
|
|
49
|
+
node-version: '20.x'
|
|
50
|
+
registry-url: 'https://registry.npmjs.org'
|
|
51
|
+
cache: 'npm'
|
|
52
|
+
env:
|
|
53
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
54
|
+
|
|
55
|
+
- name: Calculate version
|
|
56
|
+
id: version
|
|
57
|
+
run: |
|
|
58
|
+
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
|
59
|
+
|
|
60
|
+
# Check if version is manually provided
|
|
61
|
+
if [ -n "${{ github.event.inputs.version_override }}" ]; then
|
|
62
|
+
VERSION="${{ github.event.inputs.version_override }}"
|
|
63
|
+
echo "Using manual version override: $VERSION"
|
|
64
|
+
else
|
|
65
|
+
# Extract version from branch name (e.g., release-v1.0 -> 1.0)
|
|
66
|
+
BRANCH_NAME="${{ github.ref_name }}"
|
|
67
|
+
|
|
68
|
+
if [[ "$BRANCH_NAME" =~ ^release-v([0-9]+\.[0-9]+)$ ]]; then
|
|
69
|
+
BASE_VERSION="${BASH_REMATCH[1]}"
|
|
70
|
+
echo "Base version from branch: $BASE_VERSION"
|
|
71
|
+
|
|
72
|
+
# Check NPM for the latest published version matching this base version
|
|
73
|
+
LATEST_NPM_VERSION=""
|
|
74
|
+
if npm view "$PACKAGE_NAME" versions --json > /dev/null 2>&1; then
|
|
75
|
+
# Get all versions from NPM and find the latest matching the base version
|
|
76
|
+
NPM_VERSIONS=$(npm view "$PACKAGE_NAME" versions --json 2>/dev/null | grep -o "\"${BASE_VERSION}\.[0-9]*\"" | sed 's/"//g' | sort -V | tail -1)
|
|
77
|
+
if [ -n "$NPM_VERSIONS" ]; then
|
|
78
|
+
LATEST_NPM_VERSION="$NPM_VERSIONS"
|
|
79
|
+
echo "Latest published version on NPM: $LATEST_NPM_VERSION"
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Find the next available patch version
|
|
84
|
+
if [ -n "$LATEST_NPM_VERSION" ]; then
|
|
85
|
+
# Extract patch version from latest NPM version and increment
|
|
86
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$LATEST_NPM_VERSION"
|
|
87
|
+
PATCH=$((PATCH + 1))
|
|
88
|
+
VERSION="${MAJOR}.${MINOR}.${PATCH}"
|
|
89
|
+
echo "Incremented from latest NPM version: $VERSION"
|
|
90
|
+
else
|
|
91
|
+
# No version found on NPM, start from patch 0
|
|
92
|
+
PATCH=0
|
|
93
|
+
VERSION="${BASE_VERSION}.${PATCH}"
|
|
94
|
+
echo "No existing version on NPM, starting with: $VERSION"
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# Verify the version doesn't exist as a git tag
|
|
98
|
+
TAG="v${VERSION}"
|
|
99
|
+
if git tag -l "$TAG" | grep -q "^$TAG$"; then
|
|
100
|
+
echo "⚠️ Warning: Version $VERSION exists as git tag, but continuing with NPM version..."
|
|
101
|
+
fi
|
|
102
|
+
else
|
|
103
|
+
# Fallback to version from package.json and increment patch
|
|
104
|
+
echo "Branch name doesn't match release-vX.Y pattern, using version from package.json"
|
|
105
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
106
|
+
|
|
107
|
+
if [ -z "$CURRENT_VERSION" ]; then
|
|
108
|
+
echo "Error: Could not determine version from package.json"
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# Check NPM for latest version
|
|
113
|
+
LATEST_NPM_VERSION=""
|
|
114
|
+
if npm view "$PACKAGE_NAME" version > /dev/null 2>&1; then
|
|
115
|
+
LATEST_NPM_VERSION=$(npm view "$PACKAGE_NAME" version 2>/dev/null)
|
|
116
|
+
echo "Latest published version on NPM: $LATEST_NPM_VERSION"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
if [ -n "$LATEST_NPM_VERSION" ]; then
|
|
120
|
+
# Use NPM version and increment patch
|
|
121
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$LATEST_NPM_VERSION"
|
|
122
|
+
PATCH=$((PATCH + 1))
|
|
123
|
+
VERSION="${MAJOR}.${MINOR}.${PATCH}"
|
|
124
|
+
echo "Incremented from latest NPM version: $VERSION"
|
|
125
|
+
else
|
|
126
|
+
# No NPM version, increment from package.json
|
|
127
|
+
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
|
|
128
|
+
PATCH=$((PATCH + 1))
|
|
129
|
+
VERSION="${MAJOR}.${MINOR}.${PATCH}"
|
|
130
|
+
echo "Incremented from package.json version: $VERSION"
|
|
131
|
+
fi
|
|
132
|
+
fi
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
136
|
+
echo "Final version: $VERSION"
|
|
137
|
+
|
|
138
|
+
- name: Update version in package.json
|
|
139
|
+
run: |
|
|
140
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
141
|
+
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
|
142
|
+
|
|
143
|
+
echo "Current version in package.json: $CURRENT_VERSION"
|
|
144
|
+
echo "Target version: $VERSION"
|
|
145
|
+
|
|
146
|
+
if [ "$CURRENT_VERSION" == "$VERSION" ]; then
|
|
147
|
+
echo "✅ Version is already $VERSION, skipping version update"
|
|
148
|
+
else
|
|
149
|
+
echo "Updating version from $CURRENT_VERSION to $VERSION..."
|
|
150
|
+
npm version "$VERSION" --no-git-tag-version || {
|
|
151
|
+
echo "⚠️ npm version failed, trying manual update..."
|
|
152
|
+
# Fallback: manually update package.json
|
|
153
|
+
node -e "const fs = require('fs'); const pkg = require('./package.json'); pkg.version = '$VERSION'; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');"
|
|
154
|
+
echo "✅ Manually updated package.json with version $VERSION"
|
|
155
|
+
}
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
# Verify the version was set correctly
|
|
159
|
+
FINAL_VERSION=$(node -p "require('./package.json').version")
|
|
160
|
+
echo "Final version in package.json: $FINAL_VERSION"
|
|
161
|
+
|
|
162
|
+
# Show the updated version info
|
|
163
|
+
echo ""
|
|
164
|
+
echo "Package details:"
|
|
165
|
+
if command -v jq &> /dev/null; then
|
|
166
|
+
cat package.json | jq '.name, .version, .description'
|
|
167
|
+
else
|
|
168
|
+
node -p "const pkg = require('./package.json'); console.log('Name:', pkg.name); console.log('Version:', pkg.version); console.log('Description:', pkg.description);"
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
- name: Install dependencies
|
|
172
|
+
run: |
|
|
173
|
+
echo "Installing dependencies..."
|
|
174
|
+
if [ -f "package-lock.json" ]; then
|
|
175
|
+
npm ci
|
|
176
|
+
else
|
|
177
|
+
npm install
|
|
178
|
+
fi
|
|
179
|
+
echo "Dependencies installed successfully"
|
|
180
|
+
|
|
181
|
+
- name: Validate CLI syntax
|
|
182
|
+
run: |
|
|
183
|
+
echo "Validating CLI entry point..."
|
|
184
|
+
|
|
185
|
+
# Check if main bin file exists and is valid JavaScript
|
|
186
|
+
BIN_FILE="bin/workflow.js"
|
|
187
|
+
if [ -f "$BIN_FILE" ]; then
|
|
188
|
+
echo "Validating $BIN_FILE..."
|
|
189
|
+
if node -c "$BIN_FILE"; then
|
|
190
|
+
echo "✅ Valid JavaScript syntax: $BIN_FILE"
|
|
191
|
+
else
|
|
192
|
+
echo "❌ Invalid JavaScript syntax in $BIN_FILE"
|
|
193
|
+
exit 1
|
|
194
|
+
fi
|
|
195
|
+
else
|
|
196
|
+
echo "❌ Main bin file not found: $BIN_FILE"
|
|
197
|
+
exit 1
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# Check all source files for syntax errors
|
|
201
|
+
echo "Checking source files for syntax errors..."
|
|
202
|
+
# Enable globstar for recursive globbing
|
|
203
|
+
shopt -s globstar 2>/dev/null || true
|
|
204
|
+
# Use find as fallback if globstar doesn't work
|
|
205
|
+
if shopt -q globstar 2>/dev/null; then
|
|
206
|
+
for js_file in src/**/*.js; do
|
|
207
|
+
if [ -f "$js_file" ]; then
|
|
208
|
+
if node -c "$js_file"; then
|
|
209
|
+
echo "✅ Valid syntax: $js_file"
|
|
210
|
+
else
|
|
211
|
+
echo "❌ Invalid syntax: $js_file"
|
|
212
|
+
exit 1
|
|
213
|
+
fi
|
|
214
|
+
fi
|
|
215
|
+
done
|
|
216
|
+
else
|
|
217
|
+
# Fallback to find command
|
|
218
|
+
find src -name "*.js" -type f | while read -r js_file; do
|
|
219
|
+
if node -c "$js_file"; then
|
|
220
|
+
echo "✅ Valid syntax: $js_file"
|
|
221
|
+
else
|
|
222
|
+
echo "❌ Invalid syntax: $js_file"
|
|
223
|
+
exit 1
|
|
224
|
+
fi
|
|
225
|
+
done
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
echo "All files have valid JavaScript syntax"
|
|
229
|
+
|
|
230
|
+
- name: Lint code
|
|
231
|
+
run: |
|
|
232
|
+
# Run linting if available
|
|
233
|
+
if npm run lint --silent > /dev/null 2>&1; then
|
|
234
|
+
echo "Running linter..."
|
|
235
|
+
npm run lint
|
|
236
|
+
else
|
|
237
|
+
echo "No lint script found, running basic code validation..."
|
|
238
|
+
|
|
239
|
+
# Check JavaScript syntax
|
|
240
|
+
if [ -f "bin/workflow.js" ]; then
|
|
241
|
+
echo "Checking bin/workflow.js syntax..."
|
|
242
|
+
if node -c "bin/workflow.js"; then
|
|
243
|
+
echo "✅ bin/workflow.js has valid syntax"
|
|
244
|
+
else
|
|
245
|
+
echo "❌ bin/workflow.js has syntax errors"
|
|
246
|
+
exit 1
|
|
247
|
+
fi
|
|
248
|
+
fi
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
- name: Run tests
|
|
252
|
+
run: |
|
|
253
|
+
echo "Running tests..."
|
|
254
|
+
if npm run test --silent > /dev/null 2>&1; then
|
|
255
|
+
npm test
|
|
256
|
+
echo "All tests passed!"
|
|
257
|
+
else
|
|
258
|
+
echo "No test script found, running basic validation instead..."
|
|
259
|
+
|
|
260
|
+
# Basic validation - check if CLI can be executed
|
|
261
|
+
echo "Testing CLI entry point..."
|
|
262
|
+
if node bin/workflow.js --help > /dev/null 2>&1; then
|
|
263
|
+
echo "✅ CLI can be executed and shows help"
|
|
264
|
+
else
|
|
265
|
+
echo "⚠️ CLI help command returned non-zero exit code (this may be expected)"
|
|
266
|
+
fi
|
|
267
|
+
|
|
268
|
+
# Test that the module can be required
|
|
269
|
+
echo "Testing module requirements..."
|
|
270
|
+
if node -e "
|
|
271
|
+
const pkg = require('./package.json');
|
|
272
|
+
console.log('Package name:', pkg.name);
|
|
273
|
+
console.log('Package version:', pkg.version);
|
|
274
|
+
console.log('Bin commands:', Object.keys(pkg.bin || {}));
|
|
275
|
+
"; then
|
|
276
|
+
echo "✅ Module can be required and package.json is valid"
|
|
277
|
+
else
|
|
278
|
+
echo "❌ Module requirement failed"
|
|
279
|
+
exit 1
|
|
280
|
+
fi
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
- name: Build package
|
|
284
|
+
run: |
|
|
285
|
+
echo "Building package..."
|
|
286
|
+
|
|
287
|
+
# Run build script if available
|
|
288
|
+
if npm run build --silent > /dev/null 2>&1; then
|
|
289
|
+
npm run build
|
|
290
|
+
echo "Build completed successfully"
|
|
291
|
+
else
|
|
292
|
+
echo "No build script found, running prepublishOnly if available..."
|
|
293
|
+
if npm run prepublishOnly --silent > /dev/null 2>&1; then
|
|
294
|
+
npm run prepublishOnly
|
|
295
|
+
fi
|
|
296
|
+
echo "Package is ready for publishing"
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
# Create package tarball for validation
|
|
300
|
+
npm pack --dry-run
|
|
301
|
+
echo "Package validation completed"
|
|
302
|
+
|
|
303
|
+
- name: Create package tarball
|
|
304
|
+
run: |
|
|
305
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
306
|
+
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
|
307
|
+
|
|
308
|
+
# Create the package tarball
|
|
309
|
+
npm pack
|
|
310
|
+
|
|
311
|
+
# Rename to include version for clarity
|
|
312
|
+
SAFE_NAME=$(echo "$PACKAGE_NAME" | sed 's/@//g' | sed 's/\//-/g')
|
|
313
|
+
SAFE_TARBALL="${SAFE_NAME}-${VERSION}.tgz"
|
|
314
|
+
|
|
315
|
+
if [ -f "${SAFE_TARBALL}" ]; then
|
|
316
|
+
echo "Package tarball created: ${SAFE_TARBALL}"
|
|
317
|
+
else
|
|
318
|
+
# Try to find the tarball with package name
|
|
319
|
+
TARBALL=$(ls -1 ${SAFE_NAME}-*.tgz 2>/dev/null | head -1)
|
|
320
|
+
if [ -n "$TARBALL" ]; then
|
|
321
|
+
echo "Package tarball found: $TARBALL"
|
|
322
|
+
else
|
|
323
|
+
echo "⚠️ Package tarball not found, but continuing..."
|
|
324
|
+
fi
|
|
325
|
+
fi
|
|
326
|
+
|
|
327
|
+
- name: Verify NPM authentication
|
|
328
|
+
if: github.event.inputs.registry_target != 'github'
|
|
329
|
+
run: |
|
|
330
|
+
echo "🔐 Verifying NPM authentication..."
|
|
331
|
+
|
|
332
|
+
# Verify token is valid by checking whoami
|
|
333
|
+
echo "Checking NPM authentication..."
|
|
334
|
+
if npm whoami > /dev/null 2>&1; then
|
|
335
|
+
NPM_USER=$(npm whoami)
|
|
336
|
+
echo "✅ Authenticated as: $NPM_USER"
|
|
337
|
+
else
|
|
338
|
+
echo "❌ NPM authentication failed"
|
|
339
|
+
echo "Please verify that NPM_TOKEN secret is set and has the correct permissions"
|
|
340
|
+
echo "The token must be of type 'Automation' with publish permissions"
|
|
341
|
+
exit 1
|
|
342
|
+
fi
|
|
343
|
+
|
|
344
|
+
# Check if we can access the scope
|
|
345
|
+
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
|
346
|
+
SCOPE=$(echo "$PACKAGE_NAME" | cut -d'/' -f1 | sed 's/@//')
|
|
347
|
+
echo "Checking access to scope: $SCOPE"
|
|
348
|
+
|
|
349
|
+
# Try to view any package in the scope to verify access
|
|
350
|
+
if npm view "@${SCOPE}/" > /dev/null 2>&1; then
|
|
351
|
+
echo "✅ Have access to scope: $SCOPE"
|
|
352
|
+
else
|
|
353
|
+
echo "⚠️ Cannot verify scope access (this may be normal for new scopes)"
|
|
354
|
+
fi
|
|
355
|
+
|
|
356
|
+
- name: Publish to NPM
|
|
357
|
+
id: publish
|
|
358
|
+
run: |
|
|
359
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
360
|
+
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
|
361
|
+
REGISTRY_TARGET="${{ github.event.inputs.registry_target || 'npmjs' }}"
|
|
362
|
+
FORCE_PUBLISH="${{ github.event.inputs.force_publish || 'false' }}"
|
|
363
|
+
|
|
364
|
+
echo "📦 Publishing package: $PACKAGE_NAME@$VERSION"
|
|
365
|
+
echo "🎯 Target registry: $REGISTRY_TARGET"
|
|
366
|
+
echo "🔧 Force publish: $FORCE_PUBLISH"
|
|
367
|
+
|
|
368
|
+
PUBLISHED=false
|
|
369
|
+
SUCCESS_COUNT=0
|
|
370
|
+
TOTAL_ATTEMPTS=0
|
|
371
|
+
|
|
372
|
+
# Publish to NPM
|
|
373
|
+
if [ "$REGISTRY_TARGET" == "npmjs" ] || [ "$REGISTRY_TARGET" == "both" ]; then
|
|
374
|
+
TOTAL_ATTEMPTS=$((TOTAL_ATTEMPTS + 1))
|
|
375
|
+
echo ""
|
|
376
|
+
echo "📤 Publishing to NPM (npmjs.org)..."
|
|
377
|
+
|
|
378
|
+
# Verify npm configuration
|
|
379
|
+
echo "NPM registry: $(npm config get registry)"
|
|
380
|
+
echo "NPM scope registry: $(npm config get @burgan-tech:registry || echo 'not set')"
|
|
381
|
+
|
|
382
|
+
# Check if package exists on NPM
|
|
383
|
+
PACKAGE_EXISTS=false
|
|
384
|
+
if npm view "$PACKAGE_NAME" version > /dev/null 2>&1; then
|
|
385
|
+
PACKAGE_EXISTS=true
|
|
386
|
+
echo "✅ Package exists on NPM"
|
|
387
|
+
else
|
|
388
|
+
echo "ℹ️ Package does not exist on NPM yet - will create it on first publish"
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
if [ "$FORCE_PUBLISH" == "true" ]; then
|
|
392
|
+
echo "⚠️ Force publish enabled - will attempt to publish even if version exists"
|
|
393
|
+
|
|
394
|
+
# Ensure we're using the correct registry
|
|
395
|
+
npm config set registry https://registry.npmjs.org/
|
|
396
|
+
|
|
397
|
+
if npm publish --access public; then
|
|
398
|
+
echo "✅ Successfully published to NPM"
|
|
399
|
+
PUBLISHED=true
|
|
400
|
+
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
|
401
|
+
else
|
|
402
|
+
PUBLISH_EXIT_CODE=$?
|
|
403
|
+
echo "❌ NPM publish failed (exit code: $PUBLISH_EXIT_CODE)"
|
|
404
|
+
echo ""
|
|
405
|
+
echo "=== Authentication Check ==="
|
|
406
|
+
if npm whoami > /dev/null 2>&1; then
|
|
407
|
+
echo "✅ Authenticated as: $(npm whoami)"
|
|
408
|
+
else
|
|
409
|
+
echo "❌ Not authenticated"
|
|
410
|
+
fi
|
|
411
|
+
echo ""
|
|
412
|
+
echo "Please check the NPM_TOKEN permissions and ensure it has 'Automation' type."
|
|
413
|
+
exit 1
|
|
414
|
+
fi
|
|
415
|
+
else
|
|
416
|
+
# Check if version already exists (only if package exists)
|
|
417
|
+
VERSION_EXISTS=false
|
|
418
|
+
if [ "$PACKAGE_EXISTS" == "true" ]; then
|
|
419
|
+
if npm view "$PACKAGE_NAME@$VERSION" version > /dev/null 2>&1; then
|
|
420
|
+
VERSION_EXISTS=true
|
|
421
|
+
echo "❌ Version $VERSION already exists on NPM"
|
|
422
|
+
echo "💡 Tip: Use 'force_publish: true' to republish existing versions"
|
|
423
|
+
fi
|
|
424
|
+
fi
|
|
425
|
+
|
|
426
|
+
if [ "$VERSION_EXISTS" == "true" ]; then
|
|
427
|
+
echo "Skipping publish - version already exists"
|
|
428
|
+
else
|
|
429
|
+
# Try to publish (will create package if it doesn't exist)
|
|
430
|
+
if [ "$PACKAGE_EXISTS" == "false" ]; then
|
|
431
|
+
echo "📦 Creating new package on NPM..."
|
|
432
|
+
else
|
|
433
|
+
echo "📦 Publishing version $VERSION..."
|
|
434
|
+
fi
|
|
435
|
+
|
|
436
|
+
# Ensure we're using the correct registry
|
|
437
|
+
npm config set registry https://registry.npmjs.org/
|
|
438
|
+
|
|
439
|
+
# Try to publish
|
|
440
|
+
if npm publish --access public; then
|
|
441
|
+
echo "✅ Successfully published to NPM"
|
|
442
|
+
if [ "$PACKAGE_EXISTS" == "false" ]; then
|
|
443
|
+
echo "🎉 Package created successfully!"
|
|
444
|
+
fi
|
|
445
|
+
PUBLISHED=true
|
|
446
|
+
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
|
447
|
+
else
|
|
448
|
+
PUBLISH_EXIT_CODE=$?
|
|
449
|
+
echo "❌ Failed to publish to NPM (exit code: $PUBLISH_EXIT_CODE)"
|
|
450
|
+
echo ""
|
|
451
|
+
|
|
452
|
+
# Capture npm error output for debugging
|
|
453
|
+
echo "=== NPM Error Details ==="
|
|
454
|
+
npm publish --access public 2>&1 | head -20 || true
|
|
455
|
+
echo ""
|
|
456
|
+
|
|
457
|
+
echo "=== Authentication Check ==="
|
|
458
|
+
if npm whoami > /dev/null 2>&1; then
|
|
459
|
+
echo "✅ Authenticated as: $(npm whoami)"
|
|
460
|
+
else
|
|
461
|
+
echo "❌ Not authenticated"
|
|
462
|
+
fi
|
|
463
|
+
echo ""
|
|
464
|
+
|
|
465
|
+
echo "=== Registry Configuration ==="
|
|
466
|
+
echo "Registry: $(npm config get registry)"
|
|
467
|
+
echo "Scope registry: $(npm config get @burgan-tech:registry || echo 'not set')"
|
|
468
|
+
echo ""
|
|
469
|
+
|
|
470
|
+
echo "Common causes for 404 errors:"
|
|
471
|
+
echo "1. NPM_TOKEN doesn't have permission to publish to '@burgan-tech' scope"
|
|
472
|
+
echo "2. The scope '@burgan-tech' needs to be created on NPM"
|
|
473
|
+
echo "3. The token is invalid or expired"
|
|
474
|
+
echo "4. The token type is incorrect (needs 'Automation' type for CI/CD)"
|
|
475
|
+
echo ""
|
|
476
|
+
echo "To fix:"
|
|
477
|
+
echo "1. Go to https://www.npmjs.com/settings/burgan-tech/packages"
|
|
478
|
+
echo "2. Ensure the scope exists and you have publish permissions"
|
|
479
|
+
echo "3. Create a new NPM token with 'Automation' type at https://www.npmjs.com/settings/burgan-tech/tokens"
|
|
480
|
+
echo " - Token type MUST be 'Automation' (not 'Publish' or 'Read-only')"
|
|
481
|
+
echo " - The token must have 'Publish packages' permission"
|
|
482
|
+
echo "4. Update the NPM_TOKEN secret in GitHub repository settings"
|
|
483
|
+
echo " - Repository Settings > Secrets and variables > Actions > NPM_TOKEN"
|
|
484
|
+
echo ""
|
|
485
|
+
echo "Note: npm publish should automatically create the package if it doesn't exist."
|
|
486
|
+
echo "If you get a 404 error, it's usually a permissions issue with the NPM_TOKEN."
|
|
487
|
+
echo ""
|
|
488
|
+
echo "For scoped packages, ensure:"
|
|
489
|
+
echo "- The scope '@burgan-tech' exists on npmjs.com"
|
|
490
|
+
echo "- Your npm account has access to the scope"
|
|
491
|
+
echo "- The token has 'Automation' type with publish permissions"
|
|
492
|
+
exit 1
|
|
493
|
+
fi
|
|
494
|
+
fi
|
|
495
|
+
fi
|
|
496
|
+
fi
|
|
497
|
+
|
|
498
|
+
# Publish to GitHub Packages
|
|
499
|
+
if [ "$REGISTRY_TARGET" == "github" ] || [ "$REGISTRY_TARGET" == "both" ]; then
|
|
500
|
+
TOTAL_ATTEMPTS=$((TOTAL_ATTEMPTS + 1))
|
|
501
|
+
echo ""
|
|
502
|
+
echo "📤 Publishing to GitHub Packages..."
|
|
503
|
+
|
|
504
|
+
# Configure npm to use GitHub Packages
|
|
505
|
+
npm config set @burgan-tech:registry https://npm.pkg.github.com
|
|
506
|
+
npm config set //npm.pkg.github.com/:_authToken ${{ secrets.GITHUB_TOKEN }}
|
|
507
|
+
|
|
508
|
+
if [ "$FORCE_PUBLISH" == "true" ]; then
|
|
509
|
+
echo "⚠️ Force publish enabled - will attempt to publish even if version exists"
|
|
510
|
+
npm publish --access public || echo "⚠️ GitHub Packages publish failed (may already exist)"
|
|
511
|
+
else
|
|
512
|
+
# Check if version already exists (basic check)
|
|
513
|
+
if npm view "$PACKAGE_NAME@$VERSION" version > /dev/null 2>&1; then
|
|
514
|
+
echo "❌ Version $VERSION already exists on GitHub Packages"
|
|
515
|
+
echo "💡 Tip: Use 'force_publish: true' to republish existing versions"
|
|
516
|
+
else
|
|
517
|
+
if npm publish --access public; then
|
|
518
|
+
echo "✅ Successfully published to GitHub Packages"
|
|
519
|
+
PUBLISHED=true
|
|
520
|
+
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
|
521
|
+
else
|
|
522
|
+
echo "❌ Failed to publish to GitHub Packages"
|
|
523
|
+
fi
|
|
524
|
+
fi
|
|
525
|
+
fi
|
|
526
|
+
fi
|
|
527
|
+
|
|
528
|
+
echo "published=$PUBLISHED" >> $GITHUB_OUTPUT
|
|
529
|
+
|
|
530
|
+
echo "📊 Publication Summary:"
|
|
531
|
+
echo " Successfully published: $SUCCESS_COUNT/$TOTAL_ATTEMPTS registries"
|
|
532
|
+
|
|
533
|
+
if [ "$SUCCESS_COUNT" -eq 0 ]; then
|
|
534
|
+
echo "❌ Failed to publish to any registry"
|
|
535
|
+
if [ "${{ github.event.inputs.force_publish }}" != "true" ]; then
|
|
536
|
+
echo "💡 Tip: If you want to republish existing versions, use the 'force_publish' option"
|
|
537
|
+
fi
|
|
538
|
+
exit 1
|
|
539
|
+
elif [ "$SUCCESS_COUNT" -lt "$TOTAL_ATTEMPTS" ]; then
|
|
540
|
+
echo "⚠️ Some registries failed, but at least one succeeded"
|
|
541
|
+
else
|
|
542
|
+
echo "🎉 Published to all target registries successfully!"
|
|
543
|
+
fi
|
|
544
|
+
|
|
545
|
+
- name: Create Git Tag
|
|
546
|
+
if: steps.publish.outputs.published == 'true'
|
|
547
|
+
run: |
|
|
548
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
549
|
+
TAG="v$VERSION"
|
|
550
|
+
|
|
551
|
+
# Create and push the tag
|
|
552
|
+
git config user.name "github-actions[bot]"
|
|
553
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
554
|
+
|
|
555
|
+
if git tag -l "$TAG" | grep -q "^$TAG$"; then
|
|
556
|
+
echo "⚠️ Tag $TAG already exists, skipping tag creation"
|
|
557
|
+
else
|
|
558
|
+
git tag -a "$TAG" -m "Release version $VERSION"
|
|
559
|
+
git push origin "$TAG"
|
|
560
|
+
echo "✅ Created and pushed tag: $TAG"
|
|
561
|
+
fi
|
|
562
|
+
|
|
563
|
+
- name: Create GitHub Release
|
|
564
|
+
if: steps.publish.outputs.published == 'true'
|
|
565
|
+
uses: actions/create-release@v1
|
|
566
|
+
env:
|
|
567
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
568
|
+
with:
|
|
569
|
+
tag_name: v${{ steps.version.outputs.version }}
|
|
570
|
+
release_name: Release v${{ steps.version.outputs.version }}
|
|
571
|
+
body: |
|
|
572
|
+
## 🚀 Release v${{ steps.version.outputs.version }}
|
|
573
|
+
|
|
574
|
+
### 📦 Installation
|
|
575
|
+
```bash
|
|
576
|
+
npm install -g @burgan-tech/vnext-workflow-cli@${{ steps.version.outputs.version }}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### 🔗 Package Links
|
|
580
|
+
- [NPM Package](https://www.npmjs.com/package/@burgan-tech/vnext-workflow-cli)
|
|
581
|
+
- [GitHub Packages](https://github.com/${{ github.repository }}/packages)
|
|
582
|
+
|
|
583
|
+
### 📋 CLI Tool
|
|
584
|
+
This package provides a command-line interface for managing vNext workflows:
|
|
585
|
+
- Check system status (API, DB, folders)
|
|
586
|
+
- Update CSX files
|
|
587
|
+
- Update workflows
|
|
588
|
+
- Sync database
|
|
589
|
+
- Reset workflows
|
|
590
|
+
- Configuration management
|
|
591
|
+
|
|
592
|
+
### 📚 Usage
|
|
593
|
+
```bash
|
|
594
|
+
# Install globally
|
|
595
|
+
npm install -g @burgan-tech/vnext-workflow-cli
|
|
596
|
+
|
|
597
|
+
# Use the CLI
|
|
598
|
+
workflow check
|
|
599
|
+
workflow csx --all
|
|
600
|
+
workflow update --all
|
|
601
|
+
workflow sync
|
|
602
|
+
workflow reset
|
|
603
|
+
workflow config set <key> <value>
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### 📋 Changes
|
|
607
|
+
See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for detailed changes.
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
*This release was automatically created by GitHub Actions*
|
|
611
|
+
draft: false
|
|
612
|
+
prerelease: false
|
|
613
|
+
|
|
614
|
+
- name: Summary
|
|
615
|
+
if: always()
|
|
616
|
+
run: |
|
|
617
|
+
echo "## 📦 NPM Package Publishing Summary" >> $GITHUB_STEP_SUMMARY
|
|
618
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
619
|
+
echo "### Version Information" >> $GITHUB_STEP_SUMMARY
|
|
620
|
+
echo "- **Package**: \`@burgan-tech/vnext-workflow-cli\`" >> $GITHUB_STEP_SUMMARY
|
|
621
|
+
echo "- **Version**: ${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
622
|
+
echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
|
|
623
|
+
echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
|
|
624
|
+
echo "- **Published**: ${{ steps.publish.outputs.published }}" >> $GITHUB_STEP_SUMMARY
|
|
625
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
626
|
+
|
|
627
|
+
if [ -n "${{ github.event.inputs.version_override }}" ]; then
|
|
628
|
+
echo "- **Version Override**: Used manual version override" >> $GITHUB_STEP_SUMMARY
|
|
629
|
+
fi
|
|
630
|
+
|
|
631
|
+
if [ "${{ github.event.inputs.force_publish }}" == "true" ]; then
|
|
632
|
+
echo "- **Force Publish**: Enabled" >> $GITHUB_STEP_SUMMARY
|
|
633
|
+
fi
|
|
634
|
+
|
|
635
|
+
REGISTRY_TARGET="${{ github.event.inputs.registry_target || 'npmjs' }}"
|
|
636
|
+
echo "- **Target Registry**: $REGISTRY_TARGET" >> $GITHUB_STEP_SUMMARY
|
|
637
|
+
|
|
638
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
639
|
+
echo "### 📦 Package Information" >> $GITHUB_STEP_SUMMARY
|
|
640
|
+
echo "CLI tool for managing vNext workflows, tasks, schemas and more. This package provides a command-line interface for managing workflows, checking system status, updating CSX files, syncing databases, and managing configurations." >> $GITHUB_STEP_SUMMARY
|
|
641
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
642
|
+
echo "**Available Commands:**" >> $GITHUB_STEP_SUMMARY
|
|
643
|
+
echo "- \`check\` - System status check (API, DB, folders)" >> $GITHUB_STEP_SUMMARY
|
|
644
|
+
echo "- \`csx\` - Update CSX files" >> $GITHUB_STEP_SUMMARY
|
|
645
|
+
echo "- \`update\` - Update workflows" >> $GITHUB_STEP_SUMMARY
|
|
646
|
+
echo "- \`sync\` - Sync database" >> $GITHUB_STEP_SUMMARY
|
|
647
|
+
echo "- \`reset\` - Reset workflows" >> $GITHUB_STEP_SUMMARY
|
|
648
|
+
echo "- \`config\` - Configuration management" >> $GITHUB_STEP_SUMMARY
|
|
649
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
650
|
+
|
|
651
|
+
if [ "${{ steps.publish.outputs.published }}" == "true" ]; then
|
|
652
|
+
echo "### 🎉 Published Successfully!" >> $GITHUB_STEP_SUMMARY
|
|
653
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
654
|
+
echo "### 📋 Installation Instructions" >> $GITHUB_STEP_SUMMARY
|
|
655
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
656
|
+
echo "#### Install globally" >> $GITHUB_STEP_SUMMARY
|
|
657
|
+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
|
658
|
+
echo "npm install -g @burgan-tech/vnext-workflow-cli@${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
659
|
+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
660
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
661
|
+
echo "#### Install as dependency" >> $GITHUB_STEP_SUMMARY
|
|
662
|
+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
|
663
|
+
echo "npm install @burgan-tech/vnext-workflow-cli@${{ steps.version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
664
|
+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
665
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
666
|
+
echo "#### Basic Usage" >> $GITHUB_STEP_SUMMARY
|
|
667
|
+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
|
668
|
+
echo "# Check system status" >> $GITHUB_STEP_SUMMARY
|
|
669
|
+
echo "workflow check" >> $GITHUB_STEP_SUMMARY
|
|
670
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
671
|
+
echo "# Update all CSX files" >> $GITHUB_STEP_SUMMARY
|
|
672
|
+
echo "workflow csx --all" >> $GITHUB_STEP_SUMMARY
|
|
673
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
674
|
+
echo "# Update all workflows" >> $GITHUB_STEP_SUMMARY
|
|
675
|
+
echo "workflow update --all" >> $GITHUB_STEP_SUMMARY
|
|
676
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
677
|
+
echo "# Sync database" >> $GITHUB_STEP_SUMMARY
|
|
678
|
+
echo "workflow sync" >> $GITHUB_STEP_SUMMARY
|
|
679
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
680
|
+
echo "# Configuration" >> $GITHUB_STEP_SUMMARY
|
|
681
|
+
echo "workflow config set <key> <value>" >> $GITHUB_STEP_SUMMARY
|
|
682
|
+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
683
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
684
|
+
else
|
|
685
|
+
echo "### ❌ Publication Failed" >> $GITHUB_STEP_SUMMARY
|
|
686
|
+
echo "The package was not successfully published. Check the workflow logs for details." >> $GITHUB_STEP_SUMMARY
|
|
687
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
688
|
+
fi
|
|
689
|
+
|
|
690
|
+
echo "### 🔗 Quick Links" >> $GITHUB_STEP_SUMMARY
|
|
691
|
+
echo "- [NPM Package](https://www.npmjs.com/package/@burgan-tech/vnext-workflow-cli)" >> $GITHUB_STEP_SUMMARY
|
|
692
|
+
echo "- [GitHub Repository](https://github.com/${{ github.repository }})" >> $GITHUB_STEP_SUMMARY
|
|
693
|
+
echo "- [Workflow Artifacts](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
|
|
694
|
+
echo "- [Package Documentation](https://github.com/${{ github.repository }}#readme)" >> $GITHUB_STEP_SUMMARY
|
|
695
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
696
|
+
echo "### 📋 Next Steps" >> $GITHUB_STEP_SUMMARY
|
|
697
|
+
echo "1. Package will be available on NPM (may take a few minutes to appear in search)" >> $GITHUB_STEP_SUMMARY
|
|
698
|
+
echo "2. Install and use the CLI: \`npm install -g @burgan-tech/vnext-workflow-cli\`" >> $GITHUB_STEP_SUMMARY
|
|
699
|
+
echo "3. View package details and download statistics on NPM" >> $GITHUB_STEP_SUMMARY
|
|
700
|
+
echo "4. Update documentation if needed" >> $GITHUB_STEP_SUMMARY
|
|
701
|
+
echo "5. Use the CLI to manage your vNext workflows" >> $GITHUB_STEP_SUMMARY
|
|
702
|
+
|