@glpkg/cli 0.2.1 → 0.3.10
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/dist/cli.js +14 -11
- package/dist/cli.js.map +1 -1
- package/dist/commands/cleanup-registry.d.ts +6 -0
- package/dist/commands/cleanup-registry.d.ts.map +1 -0
- package/dist/commands/cleanup-registry.js +27 -0
- package/dist/commands/cleanup-registry.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +229 -79
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +7 -13
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +186 -150
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/license.js +12 -18
- package/dist/commands/license.js.map +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +156 -166
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/repo.d.ts.map +1 -1
- package/dist/commands/repo.js +94 -123
- package/dist/commands/repo.js.map +1 -1
- package/dist/commands/setup-registry.d.ts +6 -0
- package/dist/commands/setup-registry.d.ts.map +1 -0
- package/dist/commands/setup-registry.js +48 -0
- package/dist/commands/setup-registry.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/commands/publish.js
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Publish Command - Publish packages to GitLab
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const adapters_generic_1 = require("@glpkg/adapters.generic");
|
|
17
|
-
const adapters_pypi_1 = require("@glpkg/adapters.pypi");
|
|
18
|
-
const adapters_go_1 = require("@glpkg/adapters.go");
|
|
19
|
-
const adapters_nuget_1 = require("@glpkg/adapters.nuget");
|
|
20
|
-
const fallback_1 = require("@glpkg/fallback");
|
|
21
|
-
exports.publishCommand = new commander_1.Command('publish')
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import { execSync } from 'child_process';
|
|
8
|
+
import { createTokenManager, createConfigManager, createClient, incrementVersion, addPrerelease, } from '@glpkg/core';
|
|
9
|
+
import { createNpmrcManager, createPackageJsonManager, } from '@glpkg/adapters.npm';
|
|
10
|
+
import { createManifestReader, createTarballCreator, createUploader, } from '@glpkg/adapters.generic';
|
|
11
|
+
import { createPyProjectManager, createCommandExecutor as createPythonExecutor, buildProjectUploadUrl, } from '@glpkg/adapters.pypi';
|
|
12
|
+
import { createGoModManager, createCommandExecutor as createGoExecutor, normalizeVersion, } from '@glpkg/adapters.go';
|
|
13
|
+
import { createCsProjManager, createCommandExecutor as createDotNetExecutor, buildProjectPushUrl, } from '@glpkg/adapters.nuget';
|
|
14
|
+
export const publishCommand = new Command('publish')
|
|
22
15
|
.alias('pub')
|
|
23
16
|
.argument('[type]', 'Publish type: latest, dev, beta', 'latest')
|
|
24
17
|
.description('Publish package to GitLab registry')
|
|
@@ -53,7 +46,7 @@ exports.publishCommand = new commander_1.Command('publish')
|
|
|
53
46
|
}
|
|
54
47
|
}
|
|
55
48
|
catch (error) {
|
|
56
|
-
console.error(
|
|
49
|
+
console.error(chalk.red('✗'), 'Publish failed:', error.message);
|
|
57
50
|
process.exit(1);
|
|
58
51
|
}
|
|
59
52
|
});
|
|
@@ -61,24 +54,31 @@ exports.publishCommand = new commander_1.Command('publish')
|
|
|
61
54
|
* Publish npm package
|
|
62
55
|
*/
|
|
63
56
|
async function publishNpm(type, options) {
|
|
64
|
-
console.log(
|
|
57
|
+
console.log(chalk.blue.bold('glpkg publish'), chalk.gray('(npm)'));
|
|
65
58
|
console.log();
|
|
66
|
-
const tokenManager =
|
|
67
|
-
const configManager =
|
|
59
|
+
const tokenManager = createTokenManager();
|
|
60
|
+
const configManager = createConfigManager();
|
|
68
61
|
const token = tokenManager.resolveToken(options.token);
|
|
69
|
-
|
|
70
|
-
const
|
|
62
|
+
// Apply defaults (CLI options override defaults)
|
|
63
|
+
const defaultGitTag = configManager.getDefault('publish.gitTag');
|
|
64
|
+
const defaultPush = configManager.getDefault('publish.push');
|
|
65
|
+
// options.gitTag and options.push are string 'true'/'false' from CLI
|
|
66
|
+
// If not explicitly set (still 'true'), check defaults
|
|
67
|
+
const shouldGitTag = options.gitTag === 'false' ? false : (options.gitTag === 'true' ? (defaultGitTag ?? true) : true);
|
|
68
|
+
const shouldPush = options.push === 'false' ? false : (options.push === 'true' ? (defaultPush ?? true) : true);
|
|
69
|
+
const pkgManager = createPackageJsonManager();
|
|
70
|
+
const npmrcManager = createNpmrcManager();
|
|
71
71
|
// Check git status
|
|
72
72
|
if (!options.dryRun) {
|
|
73
73
|
checkGitClean(options.force);
|
|
74
74
|
}
|
|
75
75
|
// Detect project info
|
|
76
|
-
const spinner = (
|
|
76
|
+
const spinner = ora('Detecting project info...').start();
|
|
77
77
|
let projectInfo;
|
|
78
78
|
try {
|
|
79
|
-
const glabOutput =
|
|
79
|
+
const glabOutput = execSync('glab api projects/:id -X GET', { encoding: 'utf-8' });
|
|
80
80
|
const project = JSON.parse(glabOutput);
|
|
81
|
-
const client =
|
|
81
|
+
const client = createClient({ token });
|
|
82
82
|
const groupInfo = await client.getGroup(project.namespace.path);
|
|
83
83
|
projectInfo = {
|
|
84
84
|
projectId: project.id,
|
|
@@ -90,7 +90,7 @@ async function publishNpm(type, options) {
|
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
92
92
|
spinner.fail('Failed to detect project');
|
|
93
|
-
console.error(
|
|
93
|
+
console.error(chalk.yellow('→'), 'Run "glab auth login" to authenticate');
|
|
94
94
|
throw error;
|
|
95
95
|
}
|
|
96
96
|
// Setup .npmrc
|
|
@@ -109,9 +109,9 @@ async function publishNpm(type, options) {
|
|
|
109
109
|
const version = pkgManager.getVersion();
|
|
110
110
|
const name = pkgManager.getName();
|
|
111
111
|
// Publish
|
|
112
|
-
const publishSpinner = (
|
|
112
|
+
const publishSpinner = ora(`Publishing ${name}@${version}...`).start();
|
|
113
113
|
if (options.dryRun) {
|
|
114
|
-
|
|
114
|
+
execSync('npm publish --dry-run', {
|
|
115
115
|
stdio: 'inherit',
|
|
116
116
|
env: tokenManager.getEnvWithToken(token),
|
|
117
117
|
});
|
|
@@ -119,28 +119,11 @@ async function publishNpm(type, options) {
|
|
|
119
119
|
}
|
|
120
120
|
else {
|
|
121
121
|
const tag = type === 'dev' ? 'dev' : type === 'beta' ? 'beta' : 'latest';
|
|
122
|
-
|
|
122
|
+
execSync(`npm publish --tag ${tag} --registry=${registryUrl}`, {
|
|
123
123
|
stdio: 'inherit',
|
|
124
124
|
env: tokenManager.getEnvWithToken(token),
|
|
125
125
|
});
|
|
126
126
|
publishSpinner.succeed(`Published ${name}@${version}`);
|
|
127
|
-
// Save to local cache for immediate install availability
|
|
128
|
-
try {
|
|
129
|
-
const packOutput = (0, child_process_1.execSync)('npm pack --json', { encoding: 'utf-8' });
|
|
130
|
-
const packResult = JSON.parse(packOutput);
|
|
131
|
-
const tarballName = Array.isArray(packResult) ? packResult[0].filename : packResult.filename;
|
|
132
|
-
if (tarballName) {
|
|
133
|
-
const localCache = new fallback_1.LocalPackageCache();
|
|
134
|
-
const tarballPath = require('path').join(process.cwd(), tarballName);
|
|
135
|
-
await localCache.save(name, version, tarballPath);
|
|
136
|
-
// Clean up the tarball file
|
|
137
|
-
require('fs').unlinkSync(tarballPath);
|
|
138
|
-
console.log(chalk_1.default.gray('○'), 'Saved to local cache');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
// Cache save failure is not critical, continue
|
|
143
|
-
}
|
|
144
127
|
// Save package metadata
|
|
145
128
|
configManager.savePackageInfo({
|
|
146
129
|
packageName: name,
|
|
@@ -155,16 +138,16 @@ async function publishNpm(type, options) {
|
|
|
155
138
|
source: 'published',
|
|
156
139
|
});
|
|
157
140
|
// Git operations
|
|
158
|
-
if (
|
|
141
|
+
if (shouldGitTag && type !== 'dev') {
|
|
159
142
|
createGitTag(version);
|
|
160
143
|
}
|
|
161
|
-
if (
|
|
162
|
-
pushToRemote(
|
|
144
|
+
if (shouldPush) {
|
|
145
|
+
pushToRemote(shouldGitTag && type !== 'dev');
|
|
163
146
|
}
|
|
164
147
|
}
|
|
165
148
|
console.log();
|
|
166
|
-
console.log(
|
|
167
|
-
console.log(
|
|
149
|
+
console.log(chalk.green('✓'), 'Publish complete!');
|
|
150
|
+
console.log(chalk.gray('Package URL:'), `https://gitlab.com/${projectInfo.pathWithNamespace}/-/packages`);
|
|
168
151
|
}
|
|
169
152
|
finally {
|
|
170
153
|
npmrcManager.restore();
|
|
@@ -174,21 +157,21 @@ async function publishNpm(type, options) {
|
|
|
174
157
|
* Publish generic package
|
|
175
158
|
*/
|
|
176
159
|
async function publishGeneric(options) {
|
|
177
|
-
console.log(
|
|
160
|
+
console.log(chalk.blue.bold('glpkg publish'), chalk.gray('(generic)'));
|
|
178
161
|
console.log();
|
|
179
|
-
const tokenManager =
|
|
162
|
+
const tokenManager = createTokenManager();
|
|
180
163
|
const token = tokenManager.resolveToken(options.token);
|
|
181
|
-
const manifestReader =
|
|
182
|
-
const tarballCreator =
|
|
183
|
-
const uploader =
|
|
164
|
+
const manifestReader = createManifestReader();
|
|
165
|
+
const tarballCreator = createTarballCreator();
|
|
166
|
+
const uploader = createUploader('gitlab.com', token);
|
|
184
167
|
// Read manifest
|
|
185
168
|
const manifest = manifestReader.read(options.manifest);
|
|
186
|
-
console.log(
|
|
169
|
+
console.log(chalk.gray('○'), `Package: ${manifest.name}@${manifest.version}`);
|
|
187
170
|
// Detect project
|
|
188
|
-
const spinner = (
|
|
171
|
+
const spinner = ora('Detecting project...').start();
|
|
189
172
|
let projectId;
|
|
190
173
|
try {
|
|
191
|
-
const glabOutput =
|
|
174
|
+
const glabOutput = execSync('glab api projects/:id -X GET', { encoding: 'utf-8' });
|
|
192
175
|
const project = JSON.parse(glabOutput);
|
|
193
176
|
projectId = project.id;
|
|
194
177
|
spinner.succeed(`Project ID: ${projectId}`);
|
|
@@ -198,15 +181,15 @@ async function publishGeneric(options) {
|
|
|
198
181
|
throw error;
|
|
199
182
|
}
|
|
200
183
|
// Create tarball
|
|
201
|
-
const tarballSpinner = (
|
|
184
|
+
const tarballSpinner = ora('Creating tarball...').start();
|
|
202
185
|
const tarballResult = tarballCreator.create(manifest);
|
|
203
186
|
tarballSpinner.succeed(`Created: ${manifestReader.getOutputName()}`);
|
|
204
187
|
// Upload
|
|
205
188
|
if (options.dryRun) {
|
|
206
|
-
console.log(
|
|
189
|
+
console.log(chalk.yellow('→'), 'Dry-run: skipping upload');
|
|
207
190
|
}
|
|
208
191
|
else {
|
|
209
|
-
const uploadSpinner = (
|
|
192
|
+
const uploadSpinner = ora('Uploading...').start();
|
|
210
193
|
const result = await uploader.upload({
|
|
211
194
|
projectId,
|
|
212
195
|
gitlabHost: 'gitlab.com',
|
|
@@ -218,15 +201,6 @@ async function publishGeneric(options) {
|
|
|
218
201
|
});
|
|
219
202
|
if (result.success) {
|
|
220
203
|
uploadSpinner.succeed('Upload complete');
|
|
221
|
-
// Save to local cache for immediate install availability
|
|
222
|
-
try {
|
|
223
|
-
const localCache = new fallback_1.LocalPackageCache();
|
|
224
|
-
await localCache.save(manifest.name, manifest.version, tarballResult.tarballPath);
|
|
225
|
-
console.log(chalk_1.default.gray('○'), 'Saved to local cache');
|
|
226
|
-
}
|
|
227
|
-
catch {
|
|
228
|
-
// Cache save failure is not critical
|
|
229
|
-
}
|
|
230
204
|
}
|
|
231
205
|
else {
|
|
232
206
|
uploadSpinner.fail(result.error || 'Upload failed');
|
|
@@ -234,30 +208,36 @@ async function publishGeneric(options) {
|
|
|
234
208
|
}
|
|
235
209
|
}
|
|
236
210
|
console.log();
|
|
237
|
-
console.log(
|
|
211
|
+
console.log(chalk.green('✓'), 'Publish complete!');
|
|
238
212
|
}
|
|
239
213
|
/**
|
|
240
214
|
* Publish PyPI package
|
|
241
215
|
*/
|
|
242
216
|
async function publishPyPI(type, options) {
|
|
243
|
-
console.log(
|
|
217
|
+
console.log(chalk.blue.bold('glpkg publish'), chalk.gray('(pypi)'));
|
|
244
218
|
console.log();
|
|
245
|
-
const tokenManager =
|
|
219
|
+
const tokenManager = createTokenManager();
|
|
220
|
+
const configManager = createConfigManager();
|
|
246
221
|
const token = tokenManager.resolveToken(options.token);
|
|
247
|
-
|
|
248
|
-
const
|
|
222
|
+
// Apply defaults
|
|
223
|
+
const defaultGitTag = configManager.getDefault('publish.gitTag');
|
|
224
|
+
const defaultPush = configManager.getDefault('publish.push');
|
|
225
|
+
const shouldGitTag = options.gitTag === 'false' ? false : (options.gitTag === 'true' ? (defaultGitTag ?? true) : true);
|
|
226
|
+
const shouldPush = options.push === 'false' ? false : (options.push === 'true' ? (defaultPush ?? true) : true);
|
|
227
|
+
const pyprojectManager = createPyProjectManager();
|
|
228
|
+
const executor = createPythonExecutor();
|
|
249
229
|
// Check tools availability
|
|
250
230
|
if (!executor.hasBuild()) {
|
|
251
|
-
console.error(
|
|
231
|
+
console.error(chalk.red('✗'), 'python build not found. Install with: pip install build');
|
|
252
232
|
process.exit(1);
|
|
253
233
|
}
|
|
254
234
|
if (!executor.hasTwine()) {
|
|
255
|
-
console.error(
|
|
235
|
+
console.error(chalk.red('✗'), 'twine not found. Install with: pip install twine');
|
|
256
236
|
process.exit(1);
|
|
257
237
|
}
|
|
258
238
|
// Check pyproject.toml exists
|
|
259
239
|
if (!pyprojectManager.exists()) {
|
|
260
|
-
console.error(
|
|
240
|
+
console.error(chalk.red('✗'), 'pyproject.toml not found');
|
|
261
241
|
process.exit(1);
|
|
262
242
|
}
|
|
263
243
|
// Check git status
|
|
@@ -265,11 +245,11 @@ async function publishPyPI(type, options) {
|
|
|
265
245
|
checkGitClean(options.force);
|
|
266
246
|
}
|
|
267
247
|
// Detect project
|
|
268
|
-
const spinner = (
|
|
248
|
+
const spinner = ora('Detecting project...').start();
|
|
269
249
|
let projectId;
|
|
270
250
|
let pathWithNamespace;
|
|
271
251
|
try {
|
|
272
|
-
const glabOutput =
|
|
252
|
+
const glabOutput = execSync('glab api projects/:id -X GET', { encoding: 'utf-8' });
|
|
273
253
|
const project = JSON.parse(glabOutput);
|
|
274
254
|
projectId = project.id;
|
|
275
255
|
pathWithNamespace = project.path_with_namespace;
|
|
@@ -282,16 +262,16 @@ async function publishPyPI(type, options) {
|
|
|
282
262
|
// Handle version bump
|
|
283
263
|
if (options.bump) {
|
|
284
264
|
const currentVersion = pyprojectManager.getVersion();
|
|
285
|
-
const newVersion =
|
|
265
|
+
const newVersion = incrementVersion(currentVersion.replace(/-.*$/, ''), options.bump);
|
|
286
266
|
pyprojectManager.setVersion(newVersion);
|
|
287
|
-
console.log(
|
|
267
|
+
console.log(chalk.gray('○'), `Version: ${currentVersion} → ${newVersion}`);
|
|
288
268
|
}
|
|
289
269
|
const name = pyprojectManager.getName();
|
|
290
270
|
const version = pyprojectManager.getVersion();
|
|
291
|
-
console.log(
|
|
271
|
+
console.log(chalk.gray('○'), `Package: ${name}@${version}`);
|
|
292
272
|
// Build
|
|
293
273
|
if (!options.noBuild) {
|
|
294
|
-
const buildSpinner = (
|
|
274
|
+
const buildSpinner = ora('Building package...').start();
|
|
295
275
|
try {
|
|
296
276
|
executor.build();
|
|
297
277
|
buildSpinner.succeed('Build complete');
|
|
@@ -302,13 +282,13 @@ async function publishPyPI(type, options) {
|
|
|
302
282
|
}
|
|
303
283
|
}
|
|
304
284
|
// Upload with twine
|
|
305
|
-
const uploadUrl =
|
|
285
|
+
const uploadUrl = buildProjectUploadUrl(projectId);
|
|
306
286
|
if (options.dryRun) {
|
|
307
|
-
console.log(
|
|
308
|
-
console.log(
|
|
287
|
+
console.log(chalk.yellow('→'), 'Dry-run: skipping upload');
|
|
288
|
+
console.log(chalk.gray(' Would upload to:'), uploadUrl);
|
|
309
289
|
}
|
|
310
290
|
else {
|
|
311
|
-
const uploadSpinner = (
|
|
291
|
+
const uploadSpinner = ora('Uploading to GitLab PyPI registry...').start();
|
|
312
292
|
try {
|
|
313
293
|
executor.upload('dist/*', uploadUrl, {
|
|
314
294
|
username: '__token__',
|
|
@@ -316,11 +296,11 @@ async function publishPyPI(type, options) {
|
|
|
316
296
|
});
|
|
317
297
|
uploadSpinner.succeed(`Published ${name}@${version}`);
|
|
318
298
|
// Git operations
|
|
319
|
-
if (
|
|
299
|
+
if (shouldGitTag && type !== 'dev') {
|
|
320
300
|
createGitTag(version, 'pyproject.toml');
|
|
321
301
|
}
|
|
322
|
-
if (
|
|
323
|
-
pushToRemote(
|
|
302
|
+
if (shouldPush) {
|
|
303
|
+
pushToRemote(shouldGitTag && type !== 'dev');
|
|
324
304
|
}
|
|
325
305
|
}
|
|
326
306
|
catch (error) {
|
|
@@ -329,26 +309,30 @@ async function publishPyPI(type, options) {
|
|
|
329
309
|
}
|
|
330
310
|
}
|
|
331
311
|
console.log();
|
|
332
|
-
console.log(
|
|
333
|
-
console.log(
|
|
312
|
+
console.log(chalk.green('✓'), 'Publish complete!');
|
|
313
|
+
console.log(chalk.gray('Package URL:'), `https://gitlab.com/${pathWithNamespace}/-/packages`);
|
|
334
314
|
}
|
|
335
315
|
/**
|
|
336
316
|
* Publish Go module
|
|
337
317
|
* Go modules are published via git tags - GitLab automatically serves them via Go proxy
|
|
338
318
|
*/
|
|
339
319
|
async function publishGo(type, options) {
|
|
340
|
-
console.log(
|
|
320
|
+
console.log(chalk.blue.bold('glpkg publish'), chalk.gray('(go)'));
|
|
341
321
|
console.log();
|
|
342
|
-
const
|
|
343
|
-
const
|
|
322
|
+
const configManager = createConfigManager();
|
|
323
|
+
const goModManager = createGoModManager();
|
|
324
|
+
const executor = createGoExecutor();
|
|
325
|
+
// Apply defaults
|
|
326
|
+
const defaultPush = configManager.getDefault('publish.push');
|
|
327
|
+
const shouldPush = options.push === 'false' ? false : (options.push === 'true' ? (defaultPush ?? true) : true);
|
|
344
328
|
// Check Go availability
|
|
345
329
|
if (!executor.hasGo()) {
|
|
346
|
-
console.error(
|
|
330
|
+
console.error(chalk.red('✗'), 'Go not found. Please install Go.');
|
|
347
331
|
process.exit(1);
|
|
348
332
|
}
|
|
349
333
|
// Check go.mod exists
|
|
350
334
|
if (!goModManager.exists()) {
|
|
351
|
-
console.error(
|
|
335
|
+
console.error(chalk.red('✗'), 'go.mod not found');
|
|
352
336
|
process.exit(1);
|
|
353
337
|
}
|
|
354
338
|
// Check git status
|
|
@@ -358,12 +342,12 @@ async function publishGo(type, options) {
|
|
|
358
342
|
// Read module info
|
|
359
343
|
const goMod = goModManager.read();
|
|
360
344
|
const modulePath = goMod.module;
|
|
361
|
-
console.log(
|
|
345
|
+
console.log(chalk.gray('○'), `Module: ${modulePath}`);
|
|
362
346
|
// Detect project
|
|
363
|
-
const spinner = (
|
|
347
|
+
const spinner = ora('Detecting project...').start();
|
|
364
348
|
let pathWithNamespace;
|
|
365
349
|
try {
|
|
366
|
-
const glabOutput =
|
|
350
|
+
const glabOutput = execSync('glab api projects/:id -X GET', { encoding: 'utf-8' });
|
|
367
351
|
const project = JSON.parse(glabOutput);
|
|
368
352
|
pathWithNamespace = project.path_with_namespace;
|
|
369
353
|
spinner.succeed(`Project: ${pathWithNamespace}`);
|
|
@@ -377,11 +361,11 @@ async function publishGo(type, options) {
|
|
|
377
361
|
if (options.bump) {
|
|
378
362
|
// Get latest tag and bump
|
|
379
363
|
try {
|
|
380
|
-
const latestTag =
|
|
364
|
+
const latestTag = execSync('git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0"', {
|
|
381
365
|
encoding: 'utf-8',
|
|
382
366
|
}).trim();
|
|
383
367
|
const currentVersion = latestTag.replace(/^v/, '');
|
|
384
|
-
version =
|
|
368
|
+
version = normalizeVersion(incrementVersion(currentVersion, options.bump));
|
|
385
369
|
}
|
|
386
370
|
catch {
|
|
387
371
|
version = 'v0.1.0';
|
|
@@ -390,47 +374,47 @@ async function publishGo(type, options) {
|
|
|
390
374
|
else {
|
|
391
375
|
// Get version from latest tag or default
|
|
392
376
|
try {
|
|
393
|
-
version =
|
|
377
|
+
version = execSync('git describe --tags --abbrev=0 2>/dev/null', {
|
|
394
378
|
encoding: 'utf-8',
|
|
395
379
|
}).trim();
|
|
396
380
|
// Bump patch for new release
|
|
397
381
|
const currentVersion = version.replace(/^v/, '');
|
|
398
|
-
version =
|
|
382
|
+
version = normalizeVersion(incrementVersion(currentVersion, 'patch'));
|
|
399
383
|
}
|
|
400
384
|
catch {
|
|
401
385
|
version = 'v0.1.0';
|
|
402
386
|
}
|
|
403
387
|
}
|
|
404
|
-
console.log(
|
|
388
|
+
console.log(chalk.gray('○'), `Version: ${version}`);
|
|
405
389
|
// Validate module
|
|
406
|
-
const validateSpinner = (
|
|
390
|
+
const validateSpinner = ora('Validating module...').start();
|
|
407
391
|
const tidyResult = executor.modTidy();
|
|
408
392
|
if (!tidyResult.success) {
|
|
409
393
|
validateSpinner.fail('Module validation failed');
|
|
410
394
|
if (tidyResult.stderr) {
|
|
411
|
-
console.error(
|
|
395
|
+
console.error(chalk.gray(' '), tidyResult.stderr.trim());
|
|
412
396
|
}
|
|
413
397
|
throw new Error('go mod tidy failed');
|
|
414
398
|
}
|
|
415
399
|
validateSpinner.succeed('Module validated');
|
|
416
400
|
if (options.dryRun) {
|
|
417
|
-
console.log(
|
|
418
|
-
console.log(
|
|
401
|
+
console.log(chalk.yellow('→'), 'Dry-run: would create tag', version);
|
|
402
|
+
console.log(chalk.yellow('→'), 'Dry-run: would push tag to remote');
|
|
419
403
|
}
|
|
420
404
|
else {
|
|
421
405
|
// Create git tag
|
|
422
|
-
const tagSpinner = (
|
|
406
|
+
const tagSpinner = ora(`Creating tag ${version}...`).start();
|
|
423
407
|
try {
|
|
424
408
|
// Commit go.mod/go.sum if changed
|
|
425
409
|
try {
|
|
426
|
-
|
|
410
|
+
execSync('git add go.mod go.sum 2>/dev/null && git commit -m "chore: update go.mod" --allow-empty', {
|
|
427
411
|
stdio: 'pipe',
|
|
428
412
|
});
|
|
429
413
|
}
|
|
430
414
|
catch {
|
|
431
415
|
// No changes to commit
|
|
432
416
|
}
|
|
433
|
-
|
|
417
|
+
execSync(`git tag ${version}`, { stdio: 'pipe' });
|
|
434
418
|
tagSpinner.succeed(`Created tag: ${version}`);
|
|
435
419
|
}
|
|
436
420
|
catch (error) {
|
|
@@ -438,11 +422,11 @@ async function publishGo(type, options) {
|
|
|
438
422
|
throw error;
|
|
439
423
|
}
|
|
440
424
|
// Push tag
|
|
441
|
-
if (
|
|
442
|
-
const pushSpinner = (
|
|
425
|
+
if (shouldPush) {
|
|
426
|
+
const pushSpinner = ora('Pushing to remote...').start();
|
|
443
427
|
try {
|
|
444
|
-
|
|
445
|
-
|
|
428
|
+
execSync('git push', { stdio: 'pipe' });
|
|
429
|
+
execSync('git push --tags', { stdio: 'pipe' });
|
|
446
430
|
pushSpinner.succeed('Pushed to remote');
|
|
447
431
|
}
|
|
448
432
|
catch {
|
|
@@ -451,30 +435,36 @@ async function publishGo(type, options) {
|
|
|
451
435
|
}
|
|
452
436
|
}
|
|
453
437
|
console.log();
|
|
454
|
-
console.log(
|
|
455
|
-
console.log(
|
|
438
|
+
console.log(chalk.green('✓'), 'Publish complete!');
|
|
439
|
+
console.log(chalk.gray('Module URL:'), `https://gitlab.com/${pathWithNamespace}`);
|
|
456
440
|
console.log();
|
|
457
|
-
console.log(
|
|
458
|
-
console.log(
|
|
441
|
+
console.log(chalk.gray('To install:'));
|
|
442
|
+
console.log(chalk.cyan(` go get ${modulePath}@${version}`));
|
|
459
443
|
}
|
|
460
444
|
/**
|
|
461
445
|
* Publish NuGet package
|
|
462
446
|
*/
|
|
463
447
|
async function publishNuGet(type, options) {
|
|
464
|
-
console.log(
|
|
448
|
+
console.log(chalk.blue.bold('glpkg publish'), chalk.gray('(nuget)'));
|
|
465
449
|
console.log();
|
|
466
|
-
const tokenManager =
|
|
450
|
+
const tokenManager = createTokenManager();
|
|
451
|
+
const configManager = createConfigManager();
|
|
467
452
|
const token = tokenManager.resolveToken(options.token);
|
|
468
|
-
|
|
469
|
-
const
|
|
453
|
+
// Apply defaults
|
|
454
|
+
const defaultGitTag = configManager.getDefault('publish.gitTag');
|
|
455
|
+
const defaultPush = configManager.getDefault('publish.push');
|
|
456
|
+
const shouldGitTag = options.gitTag === 'false' ? false : (options.gitTag === 'true' ? (defaultGitTag ?? true) : true);
|
|
457
|
+
const shouldPush = options.push === 'false' ? false : (options.push === 'true' ? (defaultPush ?? true) : true);
|
|
458
|
+
const csprojManager = createCsProjManager();
|
|
459
|
+
const executor = createDotNetExecutor();
|
|
470
460
|
// Check dotnet CLI availability
|
|
471
461
|
if (!executor.hasDotNet()) {
|
|
472
|
-
console.error(
|
|
462
|
+
console.error(chalk.red('✗'), 'dotnet CLI not found. Please install .NET SDK.');
|
|
473
463
|
process.exit(1);
|
|
474
464
|
}
|
|
475
465
|
// Check .csproj exists
|
|
476
466
|
if (!csprojManager.exists()) {
|
|
477
|
-
console.error(
|
|
467
|
+
console.error(chalk.red('✗'), '.csproj file not found');
|
|
478
468
|
process.exit(1);
|
|
479
469
|
}
|
|
480
470
|
// Check git status
|
|
@@ -482,11 +472,11 @@ async function publishNuGet(type, options) {
|
|
|
482
472
|
checkGitClean(options.force);
|
|
483
473
|
}
|
|
484
474
|
// Detect project
|
|
485
|
-
const spinner = (
|
|
475
|
+
const spinner = ora('Detecting project...').start();
|
|
486
476
|
let projectId;
|
|
487
477
|
let pathWithNamespace;
|
|
488
478
|
try {
|
|
489
|
-
const glabOutput =
|
|
479
|
+
const glabOutput = execSync('glab api projects/:id -X GET', { encoding: 'utf-8' });
|
|
490
480
|
const project = JSON.parse(glabOutput);
|
|
491
481
|
projectId = project.id;
|
|
492
482
|
pathWithNamespace = project.path_with_namespace;
|
|
@@ -502,20 +492,20 @@ async function publishNuGet(type, options) {
|
|
|
502
492
|
let version = csprojManager.getVersion();
|
|
503
493
|
// Handle version bump
|
|
504
494
|
if (options.bump) {
|
|
505
|
-
const newVersion =
|
|
495
|
+
const newVersion = incrementVersion(version.replace(/-.*$/, ''), options.bump);
|
|
506
496
|
csprojManager.setVersion(newVersion);
|
|
507
|
-
console.log(
|
|
497
|
+
console.log(chalk.gray('○'), `Version: ${version} → ${newVersion}`);
|
|
508
498
|
version = newVersion;
|
|
509
499
|
}
|
|
510
|
-
console.log(
|
|
500
|
+
console.log(chalk.gray('○'), `Package: ${packageId}@${version}`);
|
|
511
501
|
// Build and pack
|
|
512
502
|
if (!options.noBuild) {
|
|
513
|
-
const buildSpinner = (
|
|
503
|
+
const buildSpinner = ora('Building and packing...').start();
|
|
514
504
|
const packResult = executor.pack({ configuration: 'Release' });
|
|
515
505
|
if (!packResult.success) {
|
|
516
506
|
buildSpinner.fail('Build failed');
|
|
517
507
|
if (packResult.stderr) {
|
|
518
|
-
console.error(
|
|
508
|
+
console.error(chalk.gray(' '), packResult.stderr.trim());
|
|
519
509
|
}
|
|
520
510
|
throw new Error('dotnet pack failed');
|
|
521
511
|
}
|
|
@@ -542,18 +532,18 @@ async function publishNuGet(type, options) {
|
|
|
542
532
|
}
|
|
543
533
|
}
|
|
544
534
|
if (!nupkgPath) {
|
|
545
|
-
console.error(
|
|
535
|
+
console.error(chalk.red('✗'), '.nupkg file not found');
|
|
546
536
|
process.exit(1);
|
|
547
537
|
}
|
|
548
|
-
console.log(
|
|
538
|
+
console.log(chalk.gray('○'), `Package: ${nupkgPath}`);
|
|
549
539
|
// Push to GitLab
|
|
550
|
-
const pushUrl =
|
|
540
|
+
const pushUrl = buildProjectPushUrl(projectId);
|
|
551
541
|
if (options.dryRun) {
|
|
552
|
-
console.log(
|
|
553
|
-
console.log(
|
|
542
|
+
console.log(chalk.yellow('→'), 'Dry-run: skipping push');
|
|
543
|
+
console.log(chalk.gray(' Would push to:'), pushUrl);
|
|
554
544
|
}
|
|
555
545
|
else {
|
|
556
|
-
const pushSpinner = (
|
|
546
|
+
const pushSpinner = ora('Pushing to GitLab NuGet registry...').start();
|
|
557
547
|
const pushResult = executor.push(nupkgPath, {
|
|
558
548
|
source: pushUrl,
|
|
559
549
|
apiKey: token,
|
|
@@ -562,24 +552,24 @@ async function publishNuGet(type, options) {
|
|
|
562
552
|
if (pushResult.success) {
|
|
563
553
|
pushSpinner.succeed(`Published ${packageId}@${version}`);
|
|
564
554
|
// Git operations
|
|
565
|
-
if (
|
|
555
|
+
if (shouldGitTag && type !== 'dev') {
|
|
566
556
|
createGitTag(version, csprojManager.getFilePath() || '*.csproj');
|
|
567
557
|
}
|
|
568
|
-
if (
|
|
569
|
-
pushToRemote(
|
|
558
|
+
if (shouldPush) {
|
|
559
|
+
pushToRemote(shouldGitTag && type !== 'dev');
|
|
570
560
|
}
|
|
571
561
|
}
|
|
572
562
|
else {
|
|
573
563
|
pushSpinner.fail('Push failed');
|
|
574
564
|
if (pushResult.stderr) {
|
|
575
|
-
console.error(
|
|
565
|
+
console.error(chalk.gray(' '), pushResult.stderr.trim());
|
|
576
566
|
}
|
|
577
567
|
throw new Error('dotnet nuget push failed');
|
|
578
568
|
}
|
|
579
569
|
}
|
|
580
570
|
console.log();
|
|
581
|
-
console.log(
|
|
582
|
-
console.log(
|
|
571
|
+
console.log(chalk.green('✓'), 'Publish complete!');
|
|
572
|
+
console.log(chalk.gray('Package URL:'), `https://gitlab.com/${pathWithNamespace}/-/packages`);
|
|
583
573
|
}
|
|
584
574
|
/**
|
|
585
575
|
* Bump version in package.json
|
|
@@ -590,20 +580,20 @@ async function bumpVersion(pkgManager, type, bump) {
|
|
|
590
580
|
if (type === 'dev') {
|
|
591
581
|
// Dev version: x.y.z-dev.timestamp
|
|
592
582
|
const timestamp = Date.now();
|
|
593
|
-
newVersion =
|
|
583
|
+
newVersion = addPrerelease(currentVersion.replace(/-.*$/, ''), 'dev', timestamp);
|
|
594
584
|
}
|
|
595
585
|
else if (bump) {
|
|
596
586
|
const baseVersion = currentVersion.replace(/-.*$/, '');
|
|
597
|
-
newVersion =
|
|
587
|
+
newVersion = incrementVersion(baseVersion, bump);
|
|
598
588
|
if (type === 'beta') {
|
|
599
|
-
newVersion =
|
|
589
|
+
newVersion = addPrerelease(newVersion, 'beta', 0);
|
|
600
590
|
}
|
|
601
591
|
}
|
|
602
592
|
else {
|
|
603
593
|
return; // No bump needed
|
|
604
594
|
}
|
|
605
595
|
pkgManager.setVersion(newVersion);
|
|
606
|
-
console.log(
|
|
596
|
+
console.log(chalk.gray('○'), `Version: ${currentVersion} → ${newVersion}`);
|
|
607
597
|
}
|
|
608
598
|
/**
|
|
609
599
|
* Check git working directory is clean
|
|
@@ -611,18 +601,18 @@ async function bumpVersion(pkgManager, type, bump) {
|
|
|
611
601
|
*/
|
|
612
602
|
function checkGitClean(force = false) {
|
|
613
603
|
try {
|
|
614
|
-
const status =
|
|
604
|
+
const status = execSync('git status --porcelain', { encoding: 'utf-8' });
|
|
615
605
|
if (status.trim()) {
|
|
616
606
|
if (force) {
|
|
617
|
-
console.log(
|
|
618
|
-
console.log(
|
|
619
|
-
console.log(
|
|
607
|
+
console.log(chalk.yellow('⚠'), 'Git working directory is not clean');
|
|
608
|
+
console.log(chalk.yellow(' →'), chalk.bold('It is strongly recommended to commit your changes before publishing'));
|
|
609
|
+
console.log(chalk.gray(' Continuing with --force...'));
|
|
620
610
|
console.log();
|
|
621
611
|
return false;
|
|
622
612
|
}
|
|
623
613
|
else {
|
|
624
|
-
console.error(
|
|
625
|
-
console.error(
|
|
614
|
+
console.error(chalk.red('✗'), 'Git working directory is not clean');
|
|
615
|
+
console.error(chalk.yellow('→'), 'Commit or stash changes, or use --force');
|
|
626
616
|
process.exit(1);
|
|
627
617
|
}
|
|
628
618
|
}
|
|
@@ -638,11 +628,11 @@ function checkGitClean(force = false) {
|
|
|
638
628
|
*/
|
|
639
629
|
function createGitTag(version, manifestFile = 'package.json') {
|
|
640
630
|
try {
|
|
641
|
-
|
|
631
|
+
execSync(`git add ${manifestFile} && git commit -m "chore: release v${version}" --allow-empty`, {
|
|
642
632
|
stdio: 'pipe',
|
|
643
633
|
});
|
|
644
|
-
|
|
645
|
-
console.log(
|
|
634
|
+
execSync(`git tag v${version}`, { stdio: 'pipe' });
|
|
635
|
+
console.log(chalk.gray('○'), `Created tag: v${version}`);
|
|
646
636
|
}
|
|
647
637
|
catch {
|
|
648
638
|
// Ignore errors
|
|
@@ -653,14 +643,14 @@ function createGitTag(version, manifestFile = 'package.json') {
|
|
|
653
643
|
*/
|
|
654
644
|
function pushToRemote(includeTags) {
|
|
655
645
|
try {
|
|
656
|
-
|
|
646
|
+
execSync('git push', { stdio: 'pipe' });
|
|
657
647
|
if (includeTags) {
|
|
658
|
-
|
|
648
|
+
execSync('git push --tags', { stdio: 'pipe' });
|
|
659
649
|
}
|
|
660
|
-
console.log(
|
|
650
|
+
console.log(chalk.gray('○'), 'Pushed to remote');
|
|
661
651
|
}
|
|
662
652
|
catch {
|
|
663
|
-
console.log(
|
|
653
|
+
console.log(chalk.yellow('⚠'), 'Failed to push (you can push manually)');
|
|
664
654
|
}
|
|
665
655
|
}
|
|
666
656
|
//# sourceMappingURL=publish.js.map
|