datagrok-tools 6.0.8 → 6.1.1

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.
File without changes
@@ -19,6 +19,15 @@ const confTemplate = _jsYaml.default.load(_fs.default.readFileSync(confTemplateD
19
19
  }));
20
20
  const grokDir = _path.default.join(_os.default.homedir(), '.grok');
21
21
  const confPath = _path.default.join(grokDir, 'config.yaml');
22
+ function defaultRegistry(url) {
23
+ try {
24
+ const hostname = new URL(url).hostname;
25
+ if (hostname === 'localhost' || /^[\d.]+$/.test(hostname) || hostname === '::1') return '';
26
+ return `registry.${hostname}`;
27
+ } catch (e) {
28
+ return '';
29
+ }
30
+ }
22
31
  function validateKey(key) {
23
32
  if (!key || /^([A-Za-z\d-])+$/.test(key)) return true;else return 'Developer key may only include letters, numbers, or hyphens';
24
33
  }
@@ -33,7 +42,7 @@ function generateKeyQ(server, url) {
33
42
  if (server.startsWith('local')) question.message = `Developer key for ${origin} (press ENTER to skip):`;
34
43
  return question;
35
44
  }
36
- async function addNewServer(config) {
45
+ async function addNewServer(config, askRegistry = false) {
37
46
  while (true) {
38
47
  const addServer = (await _inquirer.default.prompt({
39
48
  name: 'add-server',
@@ -53,17 +62,29 @@ async function addNewServer(config) {
53
62
  message: 'Enter a URL:'
54
63
  }))['server-url'];
55
64
  const key = (await _inquirer.default.prompt(generateKeyQ(name, url)))[name];
56
- config.servers[name] = {
65
+ const entry = {
57
66
  url,
58
67
  key
59
68
  };
69
+ if (askRegistry) {
70
+ const regDefault = defaultRegistry(url);
71
+ const reg = (await _inquirer.default.prompt({
72
+ name: 'registry',
73
+ type: 'input',
74
+ message: `Docker registry for ${name}:`,
75
+ default: regDefault || undefined
76
+ }))['registry'] || '';
77
+ if (reg) entry.registry = reg;
78
+ }
79
+ config.servers[name] = entry;
60
80
  } else break;
61
81
  }
62
82
  }
63
83
  function config(args) {
64
84
  const nOptions = Object.keys(args).length - 1;
65
- const interactiveMode = args['_'].length === 1 && (nOptions < 1 || nOptions === 1 && args.reset);
66
- const hasAddServerCommand = args['_'].length === 2 && args['_'][1] === 'add' && args.server && args.key && args.k && args.alias && (nOptions === 4 || nOptions === 5 && args.default);
85
+ const askRegistry = args.registry != null;
86
+ const interactiveMode = args['_'].length === 1 && (nOptions < 1 || nOptions === 1 && (args.reset || askRegistry) || nOptions === 2 && args.reset && askRegistry);
87
+ const hasAddServerCommand = args['_'].length === 2 && args['_'][1] === 'add' && args.server && args.key && args.k && args.alias && nOptions >= 4 && nOptions <= 6;
67
88
  if (!interactiveMode && !hasAddServerCommand) return false;
68
89
  if (!_fs.default.existsSync(grokDir)) _fs.default.mkdirSync(grokDir);
69
90
  if (!_fs.default.existsSync(confPath) || args.reset) _fs.default.writeFileSync(confPath, _jsYaml.default.dump(confTemplate));
@@ -77,10 +98,15 @@ function config(args) {
77
98
  color.error('URL parsing error. Please, provide a valid server URL.');
78
99
  return false;
79
100
  }
80
- config.servers[args.alias] = {
101
+ const server = {
81
102
  url: args.server,
82
103
  key: args.key
83
104
  };
105
+ if (args.registry != null) {
106
+ const registry = typeof args.registry === 'string' ? args.registry : defaultRegistry(args.server);
107
+ if (registry) server.registry = registry;
108
+ }
109
+ config.servers[args.alias] = server;
84
110
  color.success(`Successfully added the server to ${confPath}.`);
85
111
  console.log(`Use this command to deploy packages: grok publish ${args.alias}`);
86
112
  if (args.default) config.default = args.alias;
@@ -110,8 +136,18 @@ function config(args) {
110
136
  question.default = config['servers'][server]['key'];
111
137
  const devKey = await _inquirer.default.prompt(question);
112
138
  config['servers'][server]['key'] = devKey[server];
139
+ if (askRegistry) {
140
+ const regDefault = config['servers'][server]['registry'] || defaultRegistry(url);
141
+ const reg = (await _inquirer.default.prompt({
142
+ name: 'registry',
143
+ type: 'input',
144
+ message: `Docker registry for ${server}:`,
145
+ default: regDefault || undefined
146
+ }))['registry'] || '';
147
+ if (reg) config['servers'][server]['registry'] = reg;else delete config['servers'][server]['registry'];
148
+ }
113
149
  }
114
- await addNewServer(config);
150
+ await addNewServer(config, askRegistry);
115
151
  const defaultServer = await _inquirer.default.prompt({
116
152
  name: 'default-server',
117
153
  type: 'input',
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.dockerGen = dockerGen;
7
+ var _pythonCeleryGen = require("../utils/python-celery-gen");
8
+ var color = _interopRequireWildcard(require("../utils/color-utils"));
9
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
+ async function dockerGen(args) {
11
+ color.setVerbose(args.verbose || args.v || false);
12
+ const packageDir = process.cwd();
13
+ const generated = (0, _pythonCeleryGen.generateCeleryArtifacts)(packageDir);
14
+ if (generated) color.success('Generated Celery Docker artifacts');else console.log('No python/ directory with annotated functions found');
15
+ return true;
16
+ }
@@ -10,19 +10,20 @@ Usage: grok <command>
10
10
  Datagrok's package management tool
11
11
 
12
12
  Commands:
13
- add Add an object template
14
- api Create wrapper functions
15
- build Build a package or multiple packages
16
- check Check package content (function signatures, etc.)
17
- claude Launch Claude Code in a Datagrok dev container
18
- config Create and manage config files
19
- create Create a package
20
- init Modify a package template
21
- link Link \`datagrok-api\` and libraries for local development
22
- publish Upload a package
23
- test Run package tests
24
- testall Run packages tests
25
- migrate Migrate legacy tags to meta.role
13
+ add Add an object template
14
+ api Create wrapper functions
15
+ build Build a package or multiple packages
16
+ check Check package content (function signatures, etc.)
17
+ claude Launch Claude Code in a Datagrok dev container
18
+ config Create and manage config files
19
+ create Create a package
20
+ docker-gen Generate Celery Docker artifacts from Python functions
21
+ init Modify a package template
22
+ link Link \`datagrok-api\` and libraries for local development
23
+ publish Upload a package
24
+ test Run package tests
25
+ testall Run packages tests
26
+ migrate Migrate legacy tags to meta.role
26
27
 
27
28
  To get help on a particular command, use:
28
29
  grok <command> --help
@@ -122,13 +123,14 @@ Usage: grok config
122
123
  Create or update a configuration file
123
124
 
124
125
  Options:
125
- [--reset] [--server] [--alias] [-k | --key]
126
+ [--reset] [--server] [--alias] [-k | --key] [--registry]
126
127
 
127
128
  --reset Restore the default config file template
128
129
  --server Use to add a server to the config (\`grok config add --alias alias --server url --key key\`)
129
130
  --alias Use in conjunction with the \`server\` option to set the server name
130
131
  --key Use in conjunction with the \`server\` option to set the developer key
131
132
  --default Use in conjunction with the \`server\` option to set the added server as default
133
+ --registry Docker registry URL (default: registry.{server hostname})
132
134
  `;
133
135
  const HELP_CREATE = `
134
136
  Usage: grok create [name]
@@ -156,13 +158,14 @@ Uploads a package
156
158
  Checks for errors before publishing — the package won't be published if there are any.
157
159
 
158
160
  Options:
159
- [--all] [--refresh] [--link] [--build] [--release] [--skip-check] [-v | --verbose]
161
+ [--all] [--refresh] [--link] [--build] [--release] [--rebuild-docker] [--skip-check] [-v | --verbose]
160
162
 
161
163
  --all Publish all available packages (run in packages directory)
162
164
  --refresh Publish all available already loaded packages (run in packages directory)
163
165
  --link Link the package to local packages
164
166
  --build Builds the package
165
167
  --release Publish package as release version
168
+ --rebuild-docker Force rebuild Docker images locally before pushing to registry
166
169
  --skip-check Skip check stage
167
170
  --verbose Print detailed output
168
171
 
@@ -266,6 +269,17 @@ Options:
266
269
  --verbose Prints detailed information about linked packages
267
270
  --all Links all available packages(run in packages directory)
268
271
  `;
272
+ const HELP_DOCKER_GEN = `
273
+ Usage: grok docker-gen
274
+
275
+ Generate Celery Docker artifacts from annotated Python functions in the python/ directory.
276
+ Produces Dockerfile, tasks.yaml, and Celery entry point in dockerfiles/<name>/.
277
+
278
+ Options:
279
+ [-v | --verbose]
280
+
281
+ --verbose Print detailed output
282
+ `;
269
283
  const HELP_MIGRATE = `
270
284
  Usage: grok migrate
271
285
 
@@ -314,6 +328,7 @@ const help = exports.help = {
314
328
  claude: HELP_CLAUDE,
315
329
  config: HELP_CONFIG,
316
330
  create: HELP_CREATE,
331
+ 'docker-gen': HELP_DOCKER_GEN,
317
332
  init: HELP_INIT,
318
333
  link: HELP_LINK,
319
334
  publish: HELP_PUBLISH,
@@ -17,13 +17,15 @@ var _testUtils = require("../utils/test-utils");
17
17
  var utils = _interopRequireWildcard(require("../utils/utils"));
18
18
  var color = _interopRequireWildcard(require("../utils/color-utils"));
19
19
  var _check = require("./check");
20
+ var _pythonCeleryGen = require("../utils/python-celery-gen");
20
21
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
21
22
  // @ts-ignore
22
23
 
23
24
  // @ts-ignore
24
25
 
25
26
  const {
26
- exec
27
+ exec,
28
+ execSync
27
29
  } = require('child_process');
28
30
  const grokDir = _path.default.join(_os.default.homedir(), '.grok');
29
31
  const confPath = _path.default.join(grokDir, 'config.yaml');
@@ -35,22 +37,263 @@ let curDir = process.cwd();
35
37
  const packDir = _path.default.join(curDir, 'package.json');
36
38
  const packageFiles = ['src/package.ts', 'src/detectors.ts', 'src/package.js', 'src/detectors.js', 'src/package-test.ts', 'src/package-test.js', 'package.js', 'detectors.js'];
37
39
  let config;
38
- async function processPackage(debug, rebuild, host, devKey, packageName, dropDb, suffix, hostAlias) {
39
- // Get the server timestamps
40
+ const BLEEDING_EDGE_TAG = 'bleeding-edge';
41
+ function discoverDockerfiles(packageName, version, debug) {
42
+ const dockerfilesDir = _path.default.join(curDir, 'dockerfiles');
43
+ if (!_fs.default.existsSync(dockerfilesDir)) return [];
44
+ const results = [];
45
+ const entries = _fs.default.readdirSync(dockerfilesDir, {
46
+ withFileTypes: true
47
+ });
48
+ for (const entry of entries) {
49
+ if (!entry.isDirectory()) continue;
50
+ const dockerfilePath = _path.default.join(dockerfilesDir, entry.name, 'Dockerfile');
51
+ if (!_fs.default.existsSync(dockerfilePath)) continue;
52
+ const cleanName = utils.removeScope(packageName).replace(/-/g, '').toLowerCase();
53
+ const imageName = `${cleanName}-${entry.name.toLowerCase()}`;
54
+ const imageTag = debug ? version : `${version}.X`;
55
+ results.push({
56
+ imageName,
57
+ imageTag,
58
+ dirName: entry.name,
59
+ fullLocalName: `${imageName}:${imageTag}`
60
+ });
61
+ }
62
+ return results;
63
+ }
64
+ function dockerCommand(args) {
65
+ return execSync(`docker ${args}`, {
66
+ encoding: 'utf-8',
67
+ stdio: ['pipe', 'pipe', 'pipe']
68
+ }).trim();
69
+ }
70
+ function localImageExists(fullName) {
71
+ try {
72
+ const output = dockerCommand(`images --format "{{.Repository}}:{{.Tag}}"`);
73
+ return output.split('\n').some(line => line.trim() === fullName);
74
+ } catch {
75
+ return false;
76
+ }
77
+ }
78
+ function dockerLogin(registry, devKey) {
79
+ try {
80
+ dockerCommand(`login ${registry} -u ${devKey} -p ${devKey}`);
81
+ return true;
82
+ } catch (e) {
83
+ color.warn(`Docker login to ${registry} failed: ${e.message || e}`);
84
+ return false;
85
+ }
86
+ }
87
+ function dockerTag(source, target) {
88
+ try {
89
+ dockerCommand(`tag ${source} ${target}`);
90
+ return true;
91
+ } catch (e) {
92
+ color.error(`Failed to tag ${source} as ${target}: ${e.message || e}`);
93
+ return false;
94
+ }
95
+ }
96
+ function dockerPush(image) {
97
+ try {
98
+ dockerCommand(`push ${image}`);
99
+ return true;
100
+ } catch (e) {
101
+ color.error(`Failed to push ${image}: ${e.message || e}`);
102
+ return false;
103
+ }
104
+ }
105
+ function dockerBuild(imageName, dockerfilePath, context) {
106
+ try {
107
+ color.log(`Building Docker image ${imageName}...`);
108
+ execSync(`docker build -t ${imageName} -f ${dockerfilePath} ${context}`, {
109
+ encoding: 'utf-8',
110
+ stdio: 'inherit'
111
+ });
112
+ return true;
113
+ } catch (e) {
114
+ color.error(`Failed to build ${imageName}: ${e.message || e}`);
115
+ return false;
116
+ }
117
+ }
118
+ async function getUserLogin(host, devKey) {
119
+ let loginResp;
120
+ try {
121
+ loginResp = await (0, _nodeFetch.default)(`${host}/users/login/dev/${devKey}`, {
122
+ method: 'POST'
123
+ });
124
+ } catch (e) {
125
+ color.warn(`Cannot reach server ${host}: ${e.message || e}`);
126
+ return null;
127
+ }
128
+ if (loginResp.status !== 200) return null;
129
+ const loginData = await loginResp.json();
130
+ const token = loginData.token;
131
+ try {
132
+ const userResp = await (0, _nodeFetch.default)(`${host}/users/current`, {
133
+ headers: {
134
+ 'Authorization': token
135
+ }
136
+ });
137
+ if (userResp.status !== 200) return null;
138
+ const userData = await userResp.json();
139
+ return {
140
+ login: userData.login,
141
+ token
142
+ };
143
+ } catch (e) {
144
+ return null;
145
+ }
146
+ }
147
+ async function resolveLatestCompatible(host, devKey, dockerName) {
148
+ const userInfo = await getUserLogin(host, devKey);
149
+ if (!userInfo) return {
150
+ found: null,
151
+ serverError: `Authentication failed. Check your developer key.`
152
+ };
153
+ try {
154
+ const url = `${host}/docker/images/${encodeURIComponent(dockerName)}/latest-compatible`;
155
+ const resp = await (0, _nodeFetch.default)(url, {
156
+ headers: {
157
+ 'Authorization': userInfo.token
158
+ }
159
+ });
160
+ if (resp.status === 200) return {
161
+ found: await resp.json(),
162
+ serverError: null
163
+ };
164
+ if (resp.status === 404) return {
165
+ found: null,
166
+ serverError: null
167
+ };
168
+ return {
169
+ found: null,
170
+ serverError: `Unexpected response (HTTP ${resp.status}) from latest-compatible endpoint`
171
+ };
172
+ } catch (e) {
173
+ return {
174
+ found: null,
175
+ serverError: `Failed to query latest-compatible: ${e.message || e}`
176
+ };
177
+ }
178
+ }
179
+ async function processDockerImages(packageName, version, registry, devKey, host, rebuildDocker, zip, localTimestamps, debug) {
180
+ const dockerImages = discoverDockerfiles(packageName, version, debug);
181
+ if (dockerImages.length === 0) return;
182
+ color.log(`Found ${dockerImages.length} Dockerfile(s)`);
183
+ if (registry) dockerLogin(registry, devKey);
184
+ for (const img of dockerImages) {
185
+ let result;
186
+ if (rebuildDocker) {
187
+ const dockerfileDir = _path.default.join('dockerfiles', img.dirName);
188
+ const dockerfilePath = _path.default.join(dockerfileDir, 'Dockerfile');
189
+ if (dockerBuild(img.fullLocalName, dockerfilePath, dockerfileDir)) {
190
+ result = pushImage(img, registry);
191
+ color.success(`Built and tagged ${img.fullLocalName}`);
192
+ } else {
193
+ result = await fallbackImage(img, host, devKey, registry);
194
+ }
195
+ } else if (localImageExists(img.fullLocalName)) {
196
+ result = pushImage(img, registry);
197
+ color.success(`Found local image ${img.fullLocalName}`);
198
+ } else {
199
+ color.warn(`Local image not found. Expected: ${img.fullLocalName}`);
200
+ color.log(` Build it with: docker build -t ${img.fullLocalName} -f dockerfiles/${img.dirName}/Dockerfile dockerfiles/${img.dirName}`);
201
+ const fallback = await fallbackImage(img, host, devKey, registry);
202
+ if (fallback.serverError) {
203
+ color.error(`Cannot resolve fallback: ${fallback.serverError}`);
204
+ result = {
205
+ image: null,
206
+ fallback: true,
207
+ requestedVersion: img.imageTag
208
+ };
209
+ } else if (fallback.image) {
210
+ result = fallback;
211
+ color.warn(`Falling back to ${fallback.image}`);
212
+ } else {
213
+ // No fallback and no local image — must build
214
+ color.warn(`No fallback available. Building ${img.fullLocalName}...`);
215
+ const dockerfileDir = _path.default.join('dockerfiles', img.dirName);
216
+ const dockerfilePath = _path.default.join(dockerfileDir, 'Dockerfile');
217
+ if (dockerBuild(img.fullLocalName, dockerfilePath, dockerfileDir)) {
218
+ result = pushImage(img, registry);
219
+ color.success(`Built and tagged ${img.fullLocalName}`);
220
+ } else {
221
+ result = {
222
+ image: null,
223
+ fallback: true,
224
+ requestedVersion: img.imageTag
225
+ };
226
+ color.error(`Failed to build ${img.fullLocalName}. No container will be available.`);
227
+ }
228
+ }
229
+ }
230
+ const imageJsonPath = _path.default.join('dockerfiles', img.dirName, 'image.json');
231
+ zip.append(JSON.stringify(result, null, 2), {
232
+ name: imageJsonPath
233
+ });
234
+ localTimestamps[imageJsonPath.replace(/\\/g, '/')] = new Date().toUTCString();
235
+ color.log(`Added ${imageJsonPath}`);
236
+ }
237
+ }
238
+ function pushImage(img, registry) {
239
+ const canonicalImage = `datagrok/${img.fullLocalName}`;
240
+ if (registry) {
241
+ const remoteTag = `${registry}/${canonicalImage}`;
242
+ dockerTag(img.fullLocalName, remoteTag);
243
+ if (dockerPush(remoteTag)) return {
244
+ image: canonicalImage,
245
+ fallback: false
246
+ };
247
+ color.warn(`Push failed, image tagged locally only: ${remoteTag}`);
248
+ return {
249
+ image: canonicalImage,
250
+ fallback: false
251
+ };
252
+ }
253
+ color.warn('No registry configured. Image tagged locally only.');
254
+ return {
255
+ image: canonicalImage,
256
+ fallback: false
257
+ };
258
+ }
259
+ async function fallbackImage(img, host, devKey, registry) {
260
+ const {
261
+ found,
262
+ serverError
263
+ } = await resolveLatestCompatible(host, devKey, img.imageName);
264
+ if (serverError) return {
265
+ image: null,
266
+ fallback: true,
267
+ requestedVersion: img.imageTag,
268
+ serverError
269
+ };
270
+ if (found) return {
271
+ image: found.image,
272
+ fallback: true,
273
+ requestedVersion: img.imageTag
274
+ };
275
+ return {
276
+ image: null,
277
+ fallback: true,
278
+ requestedVersion: img.imageTag
279
+ };
280
+ }
281
+ async function processPackage(debug, rebuild, host, devKey, packageName, dropDb, suffix, hostAlias, registry, rebuildDocker) {
282
+ // Validate server connectivity and dev key
40
283
  let timestamps = {};
41
284
  let url = `${host}/packages/dev/${devKey}/${packageName}`;
42
- if (debug) {
43
- try {
44
- timestamps = await (await (0, _nodeFetch.default)(url + '/timestamps')).json();
45
- if (timestamps['#type'] === 'ApiError') {
46
- color.error(timestamps.message);
47
- return 1;
48
- }
49
- } catch (error) {
50
- if (utils.isConnectivityError(error)) color.error(`Server is possibly offline: ${host}`);
51
- if (color.isVerbose()) console.error(error);
285
+ try {
286
+ const checkResp = await (0, _nodeFetch.default)(url + '/timestamps');
287
+ const checkData = await checkResp.json();
288
+ if (checkData['#type'] === 'ApiError') {
289
+ color.error(checkData.message);
52
290
  return 1;
53
291
  }
292
+ if (debug) timestamps = checkData;
293
+ } catch (error) {
294
+ if (utils.isConnectivityError(error)) color.error(`Server is possibly offline: ${host}`);
295
+ if (color.isVerbose()) console.error(error);
296
+ return 1;
54
297
  }
55
298
  const zip = (0, _archiverPromise.default)('zip', {
56
299
  store: false
@@ -147,6 +390,17 @@ async function processPackage(debug, rebuild, host, devKey, packageName, dropDb,
147
390
  errs.forEach(e => color.error(e));
148
391
  return 1;
149
392
  }
393
+
394
+ // Generate Celery Docker artifacts from python/ if present
395
+ (0, _pythonCeleryGen.generateCeleryArtifacts)(curDir);
396
+
397
+ // Process Docker images and inject image.json into the ZIP
398
+ let dockerVersion = json.version;
399
+ if (debug) {
400
+ const userInfo = await getUserLogin(host, devKey);
401
+ if (userInfo) dockerVersion = userInfo.login;
402
+ }
403
+ await processDockerImages(packageName, dockerVersion, registry, devKey, host, rebuildDocker ?? false, zip, localTimestamps, debug);
150
404
  zip.append(JSON.stringify(localTimestamps), {
151
405
  name: 'timestamps.json'
152
406
  });
@@ -245,16 +499,22 @@ async function publishPackage(args) {
245
499
  if (nArgs === 2) host = args['_'][1];
246
500
  let key = '';
247
501
  let url = '';
502
+ let registry;
248
503
 
249
504
  // The host can be passed either as a URL or an alias
250
505
  try {
251
506
  url = new URL(host).href;
252
507
  if (url.endsWith('/')) url = url.slice(0, -1);
253
- if (url in urls) key = config['servers'][urls[url]]['key'];
508
+ if (url in urls) {
509
+ const alias = urls[url];
510
+ key = config['servers'][alias]['key'];
511
+ registry = config['servers'][alias]['registry'];
512
+ }
254
513
  } catch (error) {
255
514
  if (!(host in config.servers)) return color.error(`Unknown server alias. Please add it to ${confPath}`);
256
515
  url = config['servers'][host]['url'];
257
516
  key = config['servers'][host]['key'];
517
+ registry = config['servers'][host]['registry'];
258
518
  }
259
519
 
260
520
  // Update the developer key
@@ -285,7 +545,7 @@ async function publishPackage(args) {
285
545
  if (!args.suffix && stdout) args.suffix = stdout.toString().substring(0, 8);
286
546
  });
287
547
  await utils.delay(100);
288
- code = await processPackage(!args.release, Boolean(args.rebuild), url, key, packageName, args.dropDb ?? false, args.suffix, host);
548
+ code = await processPackage(!args.release, Boolean(args.rebuild), url, key, packageName, args.dropDb ?? false, args.suffix, host, registry, args['rebuild-docker']);
289
549
  } catch (error) {
290
550
  console.error(error);
291
551
  code = 1;