datagrok-tools 6.4.1 → 6.4.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Datagrok-tools changelog
2
2
 
3
+ ## 6.4.2 (2026-06-18)
4
+
5
+ * `grok publish` — registry-aware Docker fallback: when a package's image isn't built locally and the target server has no compatible record, `grok publish` now checks the configured registry and Docker Hub (`docker manifest inspect`) for the expected `datagrok/<name>:<version>` (and content-hashed) tag and uses it, instead of reporting "No fallback available" and failing. Fixes dependency publishes (e.g. Bio → @datagrok/chem) on CI runners where the image exists in the registry but not locally.
6
+
3
7
  ## 6.4.1 (2026-06-18)
4
8
 
5
9
  * Fixed `grok` failing with `Cannot find module './commands/build'` — the `.npmignore` `build.js` rule was unanchored and excluded the compiled `bin/commands/build.js` from the published package; anchored it to `/build.js`.
@@ -95,6 +95,30 @@ function localImageExists(fullName, checkPlatform = true) {
95
95
  return false;
96
96
  }
97
97
  }
98
+ function imageExistsInRegistry(ref) {
99
+ try {
100
+ execSync(`docker manifest inspect ${ref}`, {
101
+ stdio: ['pipe', 'pipe', 'pipe']
102
+ });
103
+ return true;
104
+ } catch {
105
+ return false;
106
+ }
107
+ }
108
+
109
+ // Looks for an already-published image in the configured registry and on Docker Hub,
110
+ // without pulling it. Prefers the content-hashed release tag (exact dockerfile match),
111
+ // then the plain version tag. Returns the canonical `datagrok/<name>:<tag>` reference
112
+ // for image.json, or null when nothing usable is published.
113
+ function resolveRegistryImage(imageName, registryTag, versionTag, registry) {
114
+ const tags = registryTag === versionTag ? [versionTag] : [registryTag, versionTag];
115
+ for (const tag of tags) {
116
+ const canonical = `datagrok/${imageName}:${tag}`;
117
+ if (registry && imageExistsInRegistry(`${registry}/${canonical}`)) return canonical;
118
+ if (imageExistsInRegistry(canonical)) return canonical;
119
+ }
120
+ return null;
121
+ }
98
122
  function dockerLogin(registry, devKey) {
99
123
  try {
100
124
  dockerCommand(`login ${registry} -u any -p ${devKey}`);
@@ -333,24 +357,37 @@ async function processDockerImages(packageName, version, registry, devKey, host,
333
357
  requestedVersion: registryTag
334
358
  };
335
359
  if (!result || result.fallback) color.warn(`Build failed. Falling back to ${fallback.image} (hash mismatch)`);
336
- } else if (skipDockerRebuild) {
337
- color.warn(`No fallback available. Skipping docker build (--skip-docker-rebuild).`);
338
- result = {
339
- image: null,
340
- fallback: true,
341
- requestedVersion: registryTag
342
- };
343
360
  } else {
344
- // No fallback and no local image must build
345
- color.warn(`No fallback available. Building ${img.fullLocalName}...`);
346
- const built = buildAndPush();
347
- if (built) result = built;else {
361
+ // The server has no compatible record, but the image may already be
362
+ // published in the configured registry / Docker Hub (e.g. pushed by an
363
+ // earlier CI run). Use it directly rather than failing or rebuilding.
364
+ const registryImage = resolveRegistryImage(img.imageName, registryTag, img.imageTag, registry);
365
+ if (registryImage) {
366
+ result = {
367
+ image: registryImage,
368
+ fallback: true,
369
+ requestedVersion: registryTag
370
+ };
371
+ color.success(`Falling back to registry image ${registryImage}`);
372
+ } else if (skipDockerRebuild) {
373
+ color.warn(`No fallback available. Skipping docker build (--skip-docker-rebuild).`);
348
374
  result = {
349
375
  image: null,
350
376
  fallback: true,
351
377
  requestedVersion: registryTag
352
378
  };
353
- color.error(`Failed to build ${img.fullLocalName}. No container will be available.`);
379
+ } else {
380
+ // No fallback and no local image — must build
381
+ color.warn(`No fallback available. Building ${img.fullLocalName}...`);
382
+ const built = buildAndPush();
383
+ if (built) result = built;else {
384
+ result = {
385
+ image: null,
386
+ fallback: true,
387
+ requestedVersion: registryTag
388
+ };
389
+ color.error(`Failed to build ${img.fullLocalName}. No container will be available.`);
390
+ }
354
391
  }
355
392
  }
356
393
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datagrok-tools",
3
- "version": "6.4.1",
3
+ "version": "6.4.2",
4
4
  "description": "Utility to upload and publish packages to Datagrok",
5
5
  "homepage": "https://github.com/datagrok-ai/public/tree/master/tools#readme",
6
6
  "dependencies": {