datagrok-tools 6.4.7 → 6.4.8
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.8 (2026-07-22)
|
|
4
|
+
|
|
5
|
+
* GROK-20452: `grok publish` — always `docker build` the tools-generated worker dirs (`dockerfiles/queue`, `dockerfiles/celery`, `dockerfiles/<app>-celery`) instead of reusing a cached local tag. The "found local image" shortcut froze the worker at whatever stock base the daemon had when the tag was first built (CI ran day-old worker code with a fresh base available); the layer cache keeps an unchanged rebuild near-instant.
|
|
6
|
+
|
|
3
7
|
## 6.4.7 (2026-07-22)
|
|
4
8
|
|
|
5
9
|
* GROK-20452: `grok publish` — generate `dockerfiles/celery` / `dockerfiles/queue` **before** gathering files for the zip. They were generated after, so the generated Dockerfile never reached the server: `meta.queue` functions fell back to a server-side container named `<pkg>-queue-celery` while the client had built `<pkg>-queue` — image validation 404'd and the worker container never started ("Container is not started" on every call).
|
|
@@ -11,6 +11,6 @@ async function dockerGen(args) {
|
|
|
11
11
|
color.setVerbose(args.verbose || args.v || false);
|
|
12
12
|
const packageDir = process.cwd();
|
|
13
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');
|
|
14
|
+
if (generated.length) color.success('Generated Celery Docker artifacts');else console.log('No python/ directory with annotated functions found');
|
|
15
15
|
return true;
|
|
16
16
|
}
|
package/bin/commands/publish.js
CHANGED
|
@@ -284,7 +284,7 @@ async function resolveLatestCompatible(host, devKey, dockerName, version, conten
|
|
|
284
284
|
};
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
|
-
async function processDockerImages(packageName, version, registry, devKey, host, rebuildDocker, zip, localTimestamps, debug, skipDockerRebuild = false) {
|
|
287
|
+
async function processDockerImages(packageName, version, registry, devKey, host, rebuildDocker, zip, localTimestamps, debug, skipDockerRebuild = false, generatedDirs = []) {
|
|
288
288
|
const dockerImages = discoverDockerfiles(packageName, version, debug);
|
|
289
289
|
if (dockerImages.length === 0) return;
|
|
290
290
|
color.log(`Found ${dockerImages.length} Dockerfile(s)`);
|
|
@@ -317,6 +317,13 @@ async function processDockerImages(packageName, version, registry, devKey, host,
|
|
|
317
317
|
dockerRemove(img.fullLocalName);
|
|
318
318
|
if (registry) dockerRemove(`${registry}/datagrok/${remoteFullName}`);
|
|
319
319
|
result = buildAndPush() ?? (await fallbackImage(img, host, devKey, registry, version, contentHash));
|
|
320
|
+
} else if (generatedDirs.includes(img.dirName)) {
|
|
321
|
+
// Generated worker dirs are just FROM the stock base: a cached local tag
|
|
322
|
+
// pins whatever base the daemon had when it was first built (CI served a
|
|
323
|
+
// day-old worker this way). Always run docker build — the layer cache
|
|
324
|
+
// makes an unchanged rebuild near-instant, and a refreshed base lands.
|
|
325
|
+
color.log(`Rebuilding generated image ${img.fullLocalName} against the current base...`);
|
|
326
|
+
result = buildAndPush() ?? (await fallbackImage(img, host, devKey, registry, version, contentHash));
|
|
320
327
|
} else {
|
|
321
328
|
// Look for registry-qualified image first, then unqualified
|
|
322
329
|
let foundLocalName = null;
|
|
@@ -473,8 +480,7 @@ async function processPackage(debug, rebuild, host, devKey, packageName, dropDb,
|
|
|
473
480
|
// never binds the queue funcs to the client-built image and falls back to a
|
|
474
481
|
// differently-named server-side container that never starts
|
|
475
482
|
// (<pkg>-queue-celery vs the built <pkg>-queue).
|
|
476
|
-
(0, _pythonCeleryGen.generateCeleryArtifacts)(curDir);
|
|
477
|
-
(0, _queueWorkerGen.generateQueueArtifacts)(curDir);
|
|
483
|
+
const generatedDockerDirs = [...(0, _pythonCeleryGen.generateCeleryArtifacts)(curDir), ...(0, _queueWorkerGen.generateQueueArtifacts)(curDir)];
|
|
478
484
|
|
|
479
485
|
// Gather the files
|
|
480
486
|
const localTimestamps = {};
|
|
@@ -572,7 +578,7 @@ async function processPackage(debug, rebuild, host, devKey, packageName, dropDb,
|
|
|
572
578
|
const userInfo = await getUserLogin(host, devKey);
|
|
573
579
|
if (userInfo) dockerVersion = userInfo.login;
|
|
574
580
|
}
|
|
575
|
-
await processDockerImages(packageName, dockerVersion, registry, devKey, host, rebuildDocker ?? false, zip, localTimestamps, debug, skipDockerRebuild ?? false);
|
|
581
|
+
await processDockerImages(packageName, dockerVersion, registry, devKey, host, rebuildDocker ?? false, zip, localTimestamps, debug, skipDockerRebuild ?? false, generatedDockerDirs);
|
|
576
582
|
zip.append(JSON.stringify(localTimestamps), {
|
|
577
583
|
name: 'timestamps.json'
|
|
578
584
|
});
|
|
@@ -230,24 +230,27 @@ function deployFolder(packageDir, folderPath, dockerSubfolder, base) {
|
|
|
230
230
|
color.log(`Generated Celery Docker artifacts in dockerfiles/${dockerSubfolder}/`);
|
|
231
231
|
return true;
|
|
232
232
|
}
|
|
233
|
+
|
|
234
|
+
/** Returns the generated dockerfiles/<dir> names (empty when nothing generated). */
|
|
233
235
|
function generateCeleryArtifacts(packageDir) {
|
|
234
236
|
const pythonDir = _path.default.join(packageDir, 'python');
|
|
235
|
-
if (!_fs.default.existsSync(pythonDir)) return
|
|
237
|
+
if (!_fs.default.existsSync(pythonDir)) return [];
|
|
236
238
|
const packageJson = JSON.parse(_fs.default.readFileSync(_path.default.join(packageDir, 'package.json'), 'utf-8'));
|
|
237
239
|
const base = (0, _utils.removeScope)(packageJson.name).toLowerCase();
|
|
238
240
|
const entries = _fs.default.readdirSync(pythonDir, {
|
|
239
241
|
withFileTypes: true
|
|
240
242
|
});
|
|
241
243
|
const isNested = entries.length > 0 && entries.every(e => e.isDirectory());
|
|
242
|
-
|
|
244
|
+
const generated = [];
|
|
243
245
|
if (isNested) {
|
|
244
246
|
for (const entry of entries) {
|
|
245
247
|
if (!entry.isDirectory()) continue;
|
|
246
248
|
const folderPath = _path.default.join(pythonDir, entry.name);
|
|
247
|
-
|
|
249
|
+
const subfolder = `${entry.name.toLowerCase()}-celery`;
|
|
250
|
+
if (deployFolder(packageDir, folderPath, subfolder, base)) generated.push(subfolder);
|
|
248
251
|
}
|
|
249
252
|
} else {
|
|
250
|
-
if (deployFolder(packageDir, pythonDir, 'celery', base)) generated
|
|
253
|
+
if (deployFolder(packageDir, pythonDir, 'celery', base)) generated.push('celery');
|
|
251
254
|
}
|
|
252
255
|
return generated;
|
|
253
256
|
}
|
|
@@ -21,11 +21,12 @@ EXPOSE 8000
|
|
|
21
21
|
/** Generates dockerfiles/queue/ for packages with \`meta.queue: true\` functions so the
|
|
22
22
|
* standard docker build/push/image.json flow covers the auto-created Node worker
|
|
23
23
|
* container (mirror of generateCeleryArtifacts for python/). The worker fetches the
|
|
24
|
-
* package bundle at runtime, so the image is just the stock worker base.
|
|
24
|
+
* package bundle at runtime, so the image is just the stock worker base.
|
|
25
|
+
* Returns the generated dockerfiles/<dir> names (empty when nothing generated). */
|
|
25
26
|
function generateQueueArtifacts(packageDir) {
|
|
26
27
|
const candidates = ['package.ts', 'package.g.ts'].map(f => _path.default.join(packageDir, 'src', f)).filter(f => _fs.default.existsSync(f));
|
|
27
28
|
const hasQueueFuncs = candidates.some(f => queueTrueRegex.test(_fs.default.readFileSync(f, 'utf-8')));
|
|
28
|
-
if (!hasQueueFuncs) return
|
|
29
|
+
if (!hasQueueFuncs) return [];
|
|
29
30
|
const dockerfilesDir = _path.default.join(packageDir, 'dockerfiles', QUEUE_DIR);
|
|
30
31
|
const dockerfilePath = _path.default.join(dockerfilesDir, 'Dockerfile');
|
|
31
32
|
_fs.default.mkdirSync(dockerfilesDir, {
|
|
@@ -38,5 +39,5 @@ function generateQueueArtifacts(packageDir) {
|
|
|
38
39
|
const containerJsonDest = _path.default.join(dockerfilesDir, 'container.json');
|
|
39
40
|
if (_fs.default.existsSync(containerJsonSrc) && !_fs.default.existsSync(containerJsonDest)) _fs.default.copyFileSync(containerJsonSrc, containerJsonDest);
|
|
40
41
|
color.log(`Generated Node worker Docker artifacts in dockerfiles/${QUEUE_DIR}/`);
|
|
41
|
-
return
|
|
42
|
+
return [QUEUE_DIR];
|
|
42
43
|
}
|
package/package.json
CHANGED