amsd-pipeline 2.0.76 → 2.0.77
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/install.sh +70 -11
- package/package.json +1 -1
package/install.sh
CHANGED
|
@@ -237,8 +237,17 @@ if [ -n "$DEST" ]; then
|
|
|
237
237
|
fi
|
|
238
238
|
fi
|
|
239
239
|
_PKG_REF="${REF:-HEAD}"
|
|
240
|
-
# FETCH
|
|
241
|
-
|
|
240
|
+
# FETCH ONLY FOR A REF THAT IS NOT HERE: a colleague packaging a release just tagged by someone
|
|
241
|
+
# else may not have it yet. Never for a ref this checkout already holds, and never unbounded or
|
|
242
|
+
# interactive — an unconditional `git fetch --tags` over ssh sat for 20 minutes with no output
|
|
243
|
+
# while packaging a local HEAD (amsd-2974 install, 2026-09-28). A fetch that cannot finish in
|
|
244
|
+
# EPAM_INSTALL_FETCH_TIMEOUT seconds is reported, and the ref check below decides.
|
|
245
|
+
if ! git -C "$_GIT_ROOT" rev-parse --verify "${_PKG_REF}^{commit}" >/dev/null 2>&1; then
|
|
246
|
+
_warn "ref '$_PKG_REF' is not in this checkout — fetching tags (at most ${EPAM_INSTALL_FETCH_TIMEOUT:-120}s)"
|
|
247
|
+
GIT_TERMINAL_PROMPT=0 GIT_SSH_COMMAND="${GIT_SSH_COMMAND:-ssh} -o BatchMode=yes -o ConnectTimeout=15" \
|
|
248
|
+
timeout "${EPAM_INSTALL_FETCH_TIMEOUT:-120}" git -C "$_GIT_ROOT" fetch --tags --quiet >/dev/null 2>&1 \
|
|
249
|
+
|| _warn "fetching tags did not complete"
|
|
250
|
+
fi
|
|
242
251
|
if ! git -C "$_GIT_ROOT" rev-parse --verify "${_PKG_REF}^{commit}" >/dev/null 2>&1; then
|
|
243
252
|
_bad "ref '$_PKG_REF' does not exist in this checkout, even after fetching tags"
|
|
244
253
|
exit 1
|
|
@@ -303,7 +312,9 @@ if [ -n "$DEST" ]; then
|
|
|
303
312
|
fi
|
|
304
313
|
|
|
305
314
|
if [ -n "$_OPCFG_TMP" ]; then
|
|
306
|
-
|
|
315
|
+
# The engine's own history of each preserved file, so a value it shipped is never mistaken for an
|
|
316
|
+
# operator edit (an unedited agent-contract.json froze the 10-01 relative-path fix out of an install).
|
|
317
|
+
restore_operator_config "$DEST" "$_OPCFG_TMP" "${_GIT_ROOT:-}"
|
|
307
318
|
rm -rf "$_OPCFG_TMP"
|
|
308
319
|
fi
|
|
309
320
|
# RESTORED AFTER the operator config, and cleaned up on its own: the two snapshots are
|
|
@@ -371,7 +382,16 @@ RUNNER="$("$NODE_BIN" -e '
|
|
|
371
382
|
const reg = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
|
|
372
383
|
const set = reg.sets[process.argv[2]];
|
|
373
384
|
const s = JSON.parse(fs.readFileSync(path.join(path.dirname(process.argv[1]), set.settingsFile), "utf8"));
|
|
374
|
-
|
|
385
|
+
const runner = Object.keys(s.runners || {})[0] || "";
|
|
386
|
+
// THE BINARY THE RUNNER NEEDS, from the map the engine itself reads (providers.json cliBinary).
|
|
387
|
+
// A runner is usually its own binary (claude, copilot) and then this changes nothing; codemie-web
|
|
388
|
+
// is not a binary — it needs `codemie` (2026-09-28). $EPAM_CLI entries keep the runner name.
|
|
389
|
+
let bin = runner;
|
|
390
|
+
try {
|
|
391
|
+
const cb = (JSON.parse(fs.readFileSync(path.join(path.dirname(process.argv[1]), "providers.json"), "utf8")).cliBinary || {})[runner];
|
|
392
|
+
if (cb && !String(cb).startsWith("$")) bin = cb;
|
|
393
|
+
} catch { /* no map: the runner name is the binary, as before */ }
|
|
394
|
+
process.stdout.write(bin);
|
|
375
395
|
' "$CONFIG/provider-sets.json" "$STACK" 2>/dev/null)"
|
|
376
396
|
if [ -n "$RUNNER" ]; then
|
|
377
397
|
if command -v "$RUNNER" >/dev/null 2>&1; then _ok "$RUNNER (the '$STACK' runner)"
|
|
@@ -397,6 +417,39 @@ else
|
|
|
397
417
|
_bad "python3 is not on PATH — 88 pipeline handlers cannot run without it"; FAILED=1
|
|
398
418
|
fi
|
|
399
419
|
|
|
420
|
+
# A PYTHON ENVIRONMENT THE STACK DECLARES (provider-sets.json pythonEnv): built here, never by hand.
|
|
421
|
+
# codemie-web declares one — the codemie-plugins toolkit its agents reach the codeline through. The
|
|
422
|
+
# path is relative to the install root; the runner reads the same declaration. pip is idempotent, so
|
|
423
|
+
# a re-install converges on the declared (pinned) packages.
|
|
424
|
+
IFS=$'\t' read -r _PYENV_PATH _PYENV_PKGS <<<"$("$NODE_BIN" -e '
|
|
425
|
+
const reg = require(process.argv[1]);
|
|
426
|
+
const e = (reg.sets[process.argv[2]] || {}).pythonEnv;
|
|
427
|
+
if (e && e.path) process.stdout.write(e.path + "\t" + (e.packages || []).join(" "));
|
|
428
|
+
' "$CONFIG/provider-sets.json" "$STACK" 2>/dev/null)"
|
|
429
|
+
if [ -n "${_PYENV_PATH:-}" ] && [ "$CHECK_ONLY" = "1" ]; then
|
|
430
|
+
# --check builds nothing: the environment and each pinned package must already be there.
|
|
431
|
+
_pyenv="$ROOT/$_PYENV_PATH"; _pymissing=""
|
|
432
|
+
for _pkg in ${_PYENV_PKGS:-}; do
|
|
433
|
+
_want="${_pkg#*==}"; [ "$_want" = "$_pkg" ] && _want=""
|
|
434
|
+
_have="$("$_pyenv/bin/python" -m pip show "${_pkg%%==*}" 2>/dev/null | sed -n 's/^Version: //p')"
|
|
435
|
+
{ [ -n "$_have" ] && { [ -z "$_want" ] || [ "$_have" = "$_want" ]; }; } || _pymissing="$_pymissing $_pkg"
|
|
436
|
+
done
|
|
437
|
+
if [ ! -x "$_pyenv/bin/python" ] || [ -n "$_pymissing" ]; then
|
|
438
|
+
_bad "the '$STACK' stack's python environment at $_PYENV_PATH is missing or incomplete (${_pymissing# }) — run the installer without --check"; FAILED=1
|
|
439
|
+
else
|
|
440
|
+
_ok "python environment for the '$STACK' stack: $_PYENV_PATH (${_PYENV_PKGS:-no packages})"
|
|
441
|
+
fi
|
|
442
|
+
elif [ -n "${_PYENV_PATH:-}" ]; then
|
|
443
|
+
_pyenv="$ROOT/$_PYENV_PATH"
|
|
444
|
+
if [ ! -x "$_pyenv/bin/python" ] && ! python3 -m venv "$_pyenv" >/dev/null 2>&1; then
|
|
445
|
+
_bad "could not create the '$STACK' stack's python environment at $_pyenv (python3 -m venv)"; FAILED=1
|
|
446
|
+
elif [ -n "${_PYENV_PKGS:-}" ] && ! "$_pyenv/bin/python" -m pip install -q --disable-pip-version-check $_PYENV_PKGS >/dev/null 2>&1; then
|
|
447
|
+
_bad "could not install ${_PYENV_PKGS} into $_pyenv — the '$STACK' stack needs them"; FAILED=1
|
|
448
|
+
else
|
|
449
|
+
_ok "python environment for the '$STACK' stack: $_PYENV_PATH (${_PYENV_PKGS:-no packages})"
|
|
450
|
+
fi
|
|
451
|
+
fi
|
|
452
|
+
|
|
400
453
|
# ── Credentials: what this stack needs, from what it declares ───────────────
|
|
401
454
|
_head "Credentials"
|
|
402
455
|
# .env.example IS GENERATED, never hand-maintained — it went stale in both directions: this repo's
|
|
@@ -608,13 +661,19 @@ if [ -n "$EPAM_PROJECT" ] && [ -d "$ROOT/orchestrations/projects/$EPAM_PROJECT"
|
|
|
608
661
|
if [ -n "$_missing" ]; then
|
|
609
662
|
_warn "project '$EPAM_PROJECT' not configured — missing:$_missing"
|
|
610
663
|
else
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
664
|
+
# SET THESE KEYS, KEEP EVERYTHING ELSE. This replaced the whole file: a project's
|
|
665
|
+
# config.env carries its pauses, baseline branch, JQL and field mappings, and every one
|
|
666
|
+
# of them was lost to five lines. Each key is replaced where it stands, or appended.
|
|
667
|
+
"$NODE_BIN" -e '
|
|
668
|
+
const fs = require("fs"); const [file, ...kv] = process.argv.slice(1);
|
|
669
|
+
let lines = fs.existsSync(file) ? fs.readFileSync(file, "utf8").split("\n") : [];
|
|
670
|
+
for (let i = 0; i < kv.length; i += 2) {
|
|
671
|
+
const k = kv[i], line = k + "=" + kv[i + 1];
|
|
672
|
+
const at = lines.findIndex((l) => new RegExp("^(export\\s+)?" + k + "=").test(l));
|
|
673
|
+
if (at >= 0) lines[at] = line; else lines.splice(lines.length && lines[lines.length - 1] === "" ? lines.length - 1 : lines.length, 0, line);
|
|
674
|
+
}
|
|
675
|
+
fs.writeFileSync(file, lines.join("\n").replace(/\n*$/, "\n"));
|
|
676
|
+
' "$_cfg" PROJECT_NAME "$EPAM_PROJECT" JIRA_URL "$JIRA_URL" JIRA_PROJECT_KEY "$JIRA_PROJECT_KEY" JIRA_CODELINE_ROOT "$JIRA_CODELINE_ROOT"
|
|
618
677
|
_ok "wrote $_cfg (JIRA_URL, JIRA_PROJECT_KEY, JIRA_CODELINE_ROOT)"
|
|
619
678
|
fi
|
|
620
679
|
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amsd-pipeline",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.77",
|
|
4
4
|
"description": "Installer for the amsd-pipeline orchestration stack. Clones, packages and provisions the full stack with one command — no separate git clone step.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"amsd-pipeline": "bin/amsd-pipeline.js"
|