@runveric/cli 0.1.1 → 0.1.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/README.md +29 -13
- package/dist/runveric.mjs +340 -225
- package/dist/runveric.mjs.map +1 -1
- package/package.json +4 -4
package/dist/runveric.mjs
CHANGED
|
@@ -214,12 +214,12 @@ var require_wire_identity = __commonJS({
|
|
|
214
214
|
});
|
|
215
215
|
exports.PROBLEM_TYPE_BASE = exports.RUNNER_PROTOCOL_VERSION = exports.PACKAGE_WORK_ITEM_VERSION = exports.ACTION_MANIFEST_API_VERSION = exports.PACKAGE_EXECUTION_PROTOCOL_VERSION = exports.PACKAGE_RESULT_PROTOCOL_VERSION = void 0;
|
|
216
216
|
exports.problemType = problemType;
|
|
217
|
-
exports.PACKAGE_RESULT_PROTOCOL_VERSION = "
|
|
218
|
-
exports.PACKAGE_EXECUTION_PROTOCOL_VERSION = "
|
|
219
|
-
exports.ACTION_MANIFEST_API_VERSION = "
|
|
220
|
-
exports.PACKAGE_WORK_ITEM_VERSION = "
|
|
221
|
-
exports.RUNNER_PROTOCOL_VERSION = "
|
|
222
|
-
exports.PROBLEM_TYPE_BASE = "https://
|
|
217
|
+
exports.PACKAGE_RESULT_PROTOCOL_VERSION = "runveric.dev/package-result/v1";
|
|
218
|
+
exports.PACKAGE_EXECUTION_PROTOCOL_VERSION = "runveric.dev/package-execution/v1";
|
|
219
|
+
exports.ACTION_MANIFEST_API_VERSION = "runveric.dev/action/v1";
|
|
220
|
+
exports.PACKAGE_WORK_ITEM_VERSION = "runveric.dev/package-work-item/v1";
|
|
221
|
+
exports.RUNNER_PROTOCOL_VERSION = "runveric.dev/runner-channel/v2";
|
|
222
|
+
exports.PROBLEM_TYPE_BASE = "https://runveric.dev/errors";
|
|
223
223
|
function problemType(slug) {
|
|
224
224
|
return `${exports.PROBLEM_TYPE_BASE}/${slug}`;
|
|
225
225
|
}
|
|
@@ -450,7 +450,7 @@ var require_catalog = __commonJS({
|
|
|
450
450
|
Object.defineProperty(exports, "__esModule", {
|
|
451
451
|
value: true
|
|
452
452
|
});
|
|
453
|
-
exports.NEW_ACTION_WINDOW_DAYS = exports.PARAMETER_CONTROLS = exports.ACTION_LIFECYCLE_LABELS = exports.INACTIVE_ACTION_LIFECYCLES = exports.RUNNABLE_ACTION_LIFECYCLES = exports.LISTED_ACTION_LIFECYCLES = exports.ACTION_LIFECYCLE_STANDING = exports.ACTION_LIFECYCLES = void 0;
|
|
453
|
+
exports.NEW_ACTION_WINDOW_DAYS = exports.PARAMETER_ORDER_KEY = exports.PARAMETER_CONTROLS = exports.ACTION_LIFECYCLE_LABELS = exports.INACTIVE_ACTION_LIFECYCLES = exports.RUNNABLE_ACTION_LIFECYCLES = exports.LISTED_ACTION_LIFECYCLES = exports.ACTION_LIFECYCLE_STANDING = exports.ACTION_LIFECYCLES = void 0;
|
|
454
454
|
exports.orderedParameterEntries = orderedParameterEntries;
|
|
455
455
|
exports.withParameterOrder = withParameterOrder;
|
|
456
456
|
exports.isNewAction = isNewAction;
|
|
@@ -513,9 +513,10 @@ var require_catalog = __commonJS({
|
|
|
513
513
|
"switch",
|
|
514
514
|
"info"
|
|
515
515
|
];
|
|
516
|
+
exports.PARAMETER_ORDER_KEY = "x-runveric-order";
|
|
516
517
|
function orderedParameterEntries(schema) {
|
|
517
518
|
const properties = schema.properties ?? {};
|
|
518
|
-
const declared = schema[
|
|
519
|
+
const declared = schema[exports.PARAMETER_ORDER_KEY] ?? [];
|
|
519
520
|
const seen = /* @__PURE__ */ new Set();
|
|
520
521
|
const ordered = [];
|
|
521
522
|
for (const id of declared) {
|
|
@@ -540,7 +541,7 @@ var require_catalog = __commonJS({
|
|
|
540
541
|
function withParameterOrder(schema) {
|
|
541
542
|
return {
|
|
542
543
|
...schema,
|
|
543
|
-
|
|
544
|
+
[exports.PARAMETER_ORDER_KEY]: Object.keys(schema.properties ?? {})
|
|
544
545
|
};
|
|
545
546
|
}
|
|
546
547
|
__name(withParameterOrder, "withParameterOrder");
|
|
@@ -916,7 +917,9 @@ var require_packages = __commonJS({
|
|
|
916
917
|
Object.defineProperty(exports, "__esModule", {
|
|
917
918
|
value: true
|
|
918
919
|
});
|
|
919
|
-
exports.PACKAGE_IMPORT_WARNING_REASONS = exports.PACKAGE_IMPORT_SKIP_REASON_LABELS = exports.PACKAGE_IMPORT_SKIP_REASONS = exports.PACKAGE_IMPORT_LIMITS = exports.PACKAGE_DRAFT_FILTER_LABELS = exports.PACKAGE_DRAFT_FILTERS = exports.PACKAGE_INTERPRETER_LABEL = exports.PARAMETER_DETECTION_UNAVAILABLE = exports.PARAMETER_DETECTION_SOURCES = exports.PACKAGE_PARAMETERS_UNRESOLVED_COPY = exports.PACKAGE_PARAMETERS_UNRESOLVED_REASONS = exports.PACKAGE_DRAFT_STATES = exports.PACKAGE_VERSION_MODES = exports.ACTION_UNRUNNABLE_REASONS = exports.PACKAGE_SOURCE_RECONNECT_OUTCOMES = exports.ADOPTION_REVIEW_DIRECTIONS = exports.ADOPTION_CHANGE_SEVERITY = exports.ADOPTION_CHANGE_KINDS = exports.ADOPTION_CHANGE_SEVERITIES = exports.ADOPTION_STATUSES = exports.PACKAGE_INTERPRETERS = exports.PACKAGE_RUNTIME_KINDS = exports.PACKAGE_RUNNER_CONNECTOR_KEY = void 0;
|
|
920
|
+
exports.PACKAGE_IMPORT_WARNING_REASONS = exports.PACKAGE_IMPORT_SKIP_REASON_LABELS = exports.PACKAGE_IMPORT_SKIP_REASONS = exports.PACKAGE_IMPORT_LIMITS = exports.PACKAGE_DRAFT_FILTER_LABELS = exports.PACKAGE_DRAFT_FILTERS = exports.PACKAGE_INTERPRETER_LABEL = exports.PARAMETER_DETECTION_UNAVAILABLE = exports.PARAMETER_DETECTION_SOURCES = exports.PACKAGE_PARAMETERS_UNRESOLVED_COPY = exports.PACKAGE_PARAMETERS_UNRESOLVED_REASONS = exports.PACKAGE_DRAFT_STATES = exports.PACKAGE_VERSION_MODES = exports.ACTION_UNRUNNABLE_REASONS = exports.PACKAGE_SOURCE_RECONNECT_OUTCOMES = exports.ADOPTION_REVIEW_DIRECTIONS = exports.ADOPTION_CHANGE_SEVERITY = exports.ADOPTION_CHANGE_KINDS = exports.ADOPTION_CHANGE_SEVERITIES = exports.ADOPTION_STATUSES = exports.PACKAGE_INTERPRETERS = exports.PACKAGE_RUNTIME_KINDS = exports.LEGACY_PACKAGE_RUNNER_CONNECTOR_KEY = exports.PACKAGE_RUNNER_CONNECTOR_KEY = void 0;
|
|
921
|
+
exports.isPackageRunnerConnectorKey = isPackageRunnerConnectorKey;
|
|
922
|
+
exports.canonicalConnectorKey = canonicalConnectorKey;
|
|
920
923
|
exports.packageSourceConnectedRemovalMessage = packageSourceConnectedRemovalMessage;
|
|
921
924
|
exports.packageVersionAdoptedRemovalMessage = packageVersionAdoptedRemovalMessage;
|
|
922
925
|
exports.actionUnrunnableCopy = actionUnrunnableCopy;
|
|
@@ -927,7 +930,16 @@ var require_packages = __commonJS({
|
|
|
927
930
|
__exportStar(require_package_provenance(), exports);
|
|
928
931
|
__exportStar(require_package_tier(), exports);
|
|
929
932
|
var brand_1 = require_brand();
|
|
930
|
-
exports.PACKAGE_RUNNER_CONNECTOR_KEY = "
|
|
933
|
+
exports.PACKAGE_RUNNER_CONNECTOR_KEY = "runveric.package-runner";
|
|
934
|
+
exports.LEGACY_PACKAGE_RUNNER_CONNECTOR_KEY = "opera.package-runner";
|
|
935
|
+
function isPackageRunnerConnectorKey(connectorKey) {
|
|
936
|
+
return connectorKey === exports.PACKAGE_RUNNER_CONNECTOR_KEY || connectorKey === exports.LEGACY_PACKAGE_RUNNER_CONNECTOR_KEY;
|
|
937
|
+
}
|
|
938
|
+
__name(isPackageRunnerConnectorKey, "isPackageRunnerConnectorKey");
|
|
939
|
+
function canonicalConnectorKey(connectorKey) {
|
|
940
|
+
return isPackageRunnerConnectorKey(connectorKey) ? exports.PACKAGE_RUNNER_CONNECTOR_KEY : connectorKey;
|
|
941
|
+
}
|
|
942
|
+
__name(canonicalConnectorKey, "canonicalConnectorKey");
|
|
931
943
|
exports.PACKAGE_RUNTIME_KINDS = [
|
|
932
944
|
"interpreter",
|
|
933
945
|
"oci"
|
|
@@ -1248,7 +1260,7 @@ var require_packages = __commonJS({
|
|
|
1248
1260
|
"editor_metadata",
|
|
1249
1261
|
"os_metadata",
|
|
1250
1262
|
"lockfile",
|
|
1251
|
-
"
|
|
1263
|
+
"runveric_scratch",
|
|
1252
1264
|
"not_text"
|
|
1253
1265
|
];
|
|
1254
1266
|
exports.PACKAGE_IMPORT_SKIP_REASON_LABELS = {
|
|
@@ -1258,7 +1270,7 @@ var require_packages = __commonJS({
|
|
|
1258
1270
|
editor_metadata: "editor settings",
|
|
1259
1271
|
os_metadata: "operating-system metadata",
|
|
1260
1272
|
lockfile: "a dependency lockfile",
|
|
1261
|
-
|
|
1273
|
+
runveric_scratch: "scratch written by `runveric test`",
|
|
1262
1274
|
not_text: "not UTF-8 text"
|
|
1263
1275
|
};
|
|
1264
1276
|
exports.PACKAGE_IMPORT_WARNING_REASONS = [
|
|
@@ -2352,18 +2364,18 @@ var require_package_execution = __commonJS({
|
|
|
2352
2364
|
exports.PACKAGE_CONTAINER_ENV = {
|
|
2353
2365
|
/** The control-plane origin the container redeems its work item at and reports to. */
|
|
2354
2366
|
callbackBaseUrl: "OPERA_CALLBACK_BASE_URL",
|
|
2355
|
-
executionId: "
|
|
2367
|
+
executionId: "RUNVERIC_EXECUTION_ID",
|
|
2356
2368
|
/** Single-use; spent on the first redemption. Never copied into the package's own env. */
|
|
2357
2369
|
runToken: "OPERA_RUN_TOKEN",
|
|
2358
2370
|
/** What the bytes it fetched must hash to. Travels beside the work item, never inside it. */
|
|
2359
|
-
contentDigest: "
|
|
2371
|
+
contentDigest: "RUNVERIC_CONTENT_DIGEST",
|
|
2360
2372
|
/** Which runtime image this is, recorded on the run. */
|
|
2361
2373
|
runnerImageDigest: "OPERA_RUNNER_IMAGE_DIGEST",
|
|
2362
2374
|
/** Where the PACKAGE's outbound traffic is pointed. Absent when it declared no network. */
|
|
2363
|
-
egressProxyUrl: "
|
|
2375
|
+
egressProxyUrl: "RUNVERIC_EGRESS_PROXY_URL",
|
|
2364
2376
|
/** The runner-only control channel. Never copied into the package's own env. */
|
|
2365
|
-
egressControlUrl: "
|
|
2366
|
-
egressControlToken: "
|
|
2377
|
+
egressControlUrl: "RUNVERIC_EGRESS_CONTROL_URL",
|
|
2378
|
+
egressControlToken: "RUNVERIC_EGRESS_CONTROL_TOKEN"
|
|
2367
2379
|
};
|
|
2368
2380
|
}
|
|
2369
2381
|
});
|
|
@@ -2375,17 +2387,17 @@ var require_runner_confinement = __commonJS({
|
|
|
2375
2387
|
Object.defineProperty(exports, "__esModule", {
|
|
2376
2388
|
value: true
|
|
2377
2389
|
});
|
|
2378
|
-
exports.
|
|
2390
|
+
exports.CONFINEMENT_FINDING_LABEL = exports.CONFINEMENT_FINDING_SENTENCE = exports.RUNNER_ISOLATION_BLOCKS_UNDECLARED_EGRESS = exports.CONFINEMENT_FINDING_BLOCKS_EGRESS = exports.CONFINEMENT_FINDINGS = exports.RUNNER_SUBSTRATE_LABEL = exports.RUNNER_SUBSTRATES = exports.EGRESS_GATE_SHUT = exports.EGRESS_GATE_OPEN = exports.EGRESS_GATE_PREFIX = exports.EGRESS_PROBE_TIMEOUT_MS = exports.EGRESS_PROBE_BLOCKED = exports.EGRESS_PROBE_REACHED = exports.EGRESS_PROBE_PREFIX = void 0;
|
|
2379
2391
|
exports.effectiveBlocksUndeclaredEgress = effectiveBlocksUndeclaredEgress;
|
|
2380
2392
|
exports.confinementOverclaims = confinementOverclaims;
|
|
2381
2393
|
exports.runnerBlocksUndeclaredEgress = runnerBlocksUndeclaredEgress;
|
|
2382
2394
|
exports.poolConfinementSentence = poolConfinementSentence;
|
|
2383
2395
|
var brand_1 = require_brand();
|
|
2384
|
-
exports.EGRESS_PROBE_PREFIX = "
|
|
2396
|
+
exports.EGRESS_PROBE_PREFIX = "runveric.egress-probe";
|
|
2385
2397
|
exports.EGRESS_PROBE_REACHED = "REACHED";
|
|
2386
2398
|
exports.EGRESS_PROBE_BLOCKED = "BLOCKED";
|
|
2387
2399
|
exports.EGRESS_PROBE_TIMEOUT_MS = 5e3;
|
|
2388
|
-
exports.EGRESS_GATE_PREFIX = "
|
|
2400
|
+
exports.EGRESS_GATE_PREFIX = "runveric.egress-gate";
|
|
2389
2401
|
exports.EGRESS_GATE_OPEN = "OPEN";
|
|
2390
2402
|
exports.EGRESS_GATE_SHUT = "SHUT";
|
|
2391
2403
|
exports.RUNNER_SUBSTRATES = [
|
|
@@ -2440,7 +2452,69 @@ var require_runner_confinement = __commonJS({
|
|
|
2440
2452
|
return `Only ${confined} of ${findings.length} runners in this pool block undeclared outbound traffic. A run cannot choose which runner claims it, so this pool is not relied on to confine egress and packages that need their allowlist enforced are not sent here.`;
|
|
2441
2453
|
}
|
|
2442
2454
|
__name(poolConfinementSentence, "poolConfinementSentence");
|
|
2443
|
-
|
|
2455
|
+
}
|
|
2456
|
+
});
|
|
2457
|
+
|
|
2458
|
+
// ../contracts/dist/runner-install.js
|
|
2459
|
+
var require_runner_install = __commonJS({
|
|
2460
|
+
"../contracts/dist/runner-install.js"(exports) {
|
|
2461
|
+
"use strict";
|
|
2462
|
+
Object.defineProperty(exports, "__esModule", {
|
|
2463
|
+
value: true
|
|
2464
|
+
});
|
|
2465
|
+
exports.POD_ROLE_BROKER = exports.POD_EGRESS_CONFINED = exports.POD_EGRESS_LABEL = exports.POD_RUNNER = exports.POD_ROLE = exports.POD_MANAGED_BY_VALUE = exports.POD_MANAGED_BY = exports.RUNNER_NETWORK_POLICY_NAME = exports.RUNNER_REPORT_DIRECTORY = exports.RUNNER_STATE_DIRECTORY = exports.RUNNER_CONTAINER_PREFIX = exports.RUNNER_NAMESPACE = exports.RUNNER_HOST_ENV = void 0;
|
|
2466
|
+
exports.RUNNER_HOST_ENV = {
|
|
2467
|
+
/** `docker` or `kubernetes`. Absent means `docker`; present and wrong is refused by name. */
|
|
2468
|
+
substrate: "RUNVERIC_RUNNER_SUBSTRATE",
|
|
2469
|
+
/** The https origin the runner long-polls. */
|
|
2470
|
+
controlPlaneUrl: "RUNVERIC_CONTROL_PLANE_URL",
|
|
2471
|
+
/** The operator-chosen name, also the container's and the Deployment's. */
|
|
2472
|
+
runnerName: "RUNVERIC_RUNNER_NAME",
|
|
2473
|
+
/** Single-use; spent by the first registration. */
|
|
2474
|
+
registrationToken: "RUNVERIC_RUNNER_REGISTRATION_TOKEN",
|
|
2475
|
+
/** The image the dispatcher starts one container of per step. */
|
|
2476
|
+
stepImage: "RUNVERIC_RUNNER_STEP_IMAGE",
|
|
2477
|
+
/** Optional. Absent means the runner runs built-in actions only. */
|
|
2478
|
+
packageImage: "RUNVERIC_RUNNER_PACKAGE_IMAGE",
|
|
2479
|
+
/** Where the credential and the stashed reports live across restarts. */
|
|
2480
|
+
reportDirectory: "RUNVERIC_RUNNER_REPORT_DIR"
|
|
2481
|
+
};
|
|
2482
|
+
exports.RUNNER_NAMESPACE = "runveric-runner";
|
|
2483
|
+
exports.RUNNER_CONTAINER_PREFIX = "runveric-";
|
|
2484
|
+
exports.RUNNER_STATE_DIRECTORY = "/var/lib/runveric-runner";
|
|
2485
|
+
exports.RUNNER_REPORT_DIRECTORY = `${exports.RUNNER_STATE_DIRECTORY}/reports`;
|
|
2486
|
+
exports.RUNNER_NETWORK_POLICY_NAME = "runveric-confined-egress";
|
|
2487
|
+
exports.POD_MANAGED_BY = "runveric.dev/managed-by";
|
|
2488
|
+
exports.POD_MANAGED_BY_VALUE = "runveric-dispatcher";
|
|
2489
|
+
exports.POD_ROLE = "runveric.dev/role";
|
|
2490
|
+
exports.POD_RUNNER = "runveric.dev/runner";
|
|
2491
|
+
exports.POD_EGRESS_LABEL = "runveric.dev/egress";
|
|
2492
|
+
exports.POD_EGRESS_CONFINED = "confined";
|
|
2493
|
+
exports.POD_ROLE_BROKER = "egress-broker";
|
|
2494
|
+
}
|
|
2495
|
+
});
|
|
2496
|
+
|
|
2497
|
+
// ../contracts/dist/authoring-cli.js
|
|
2498
|
+
var require_authoring_cli = __commonJS({
|
|
2499
|
+
"../contracts/dist/authoring-cli.js"(exports) {
|
|
2500
|
+
"use strict";
|
|
2501
|
+
Object.defineProperty(exports, "__esModule", {
|
|
2502
|
+
value: true
|
|
2503
|
+
});
|
|
2504
|
+
exports.RETIRED_AUTHORING_CLI_ENV = exports.AUTHORING_CLI_ENV = void 0;
|
|
2505
|
+
exports.AUTHORING_CLI_ENV = {
|
|
2506
|
+
/** `runveric publish`: the access token. */
|
|
2507
|
+
token: "RUNVERIC_TOKEN",
|
|
2508
|
+
/** `runveric publish`: the control plane's origin. */
|
|
2509
|
+
url: "RUNVERIC_URL",
|
|
2510
|
+
/** `runveric test`: the runner image to run in, digest-pinned — the Author page shows it. */
|
|
2511
|
+
runnerImage: "RUNVERIC_RUNNER_IMAGE"
|
|
2512
|
+
};
|
|
2513
|
+
exports.RETIRED_AUTHORING_CLI_ENV = {
|
|
2514
|
+
token: "OPERA_TOKEN",
|
|
2515
|
+
url: "OPERA_URL",
|
|
2516
|
+
runnerImage: "OPERA_RUNNER_IMAGE"
|
|
2517
|
+
};
|
|
2444
2518
|
}
|
|
2445
2519
|
});
|
|
2446
2520
|
|
|
@@ -2464,9 +2538,10 @@ var require_runners = __commonJS({
|
|
|
2464
2538
|
}, "get")
|
|
2465
2539
|
});
|
|
2466
2540
|
var package_provenance_1 = require_package_provenance();
|
|
2467
|
-
|
|
2468
|
-
exports.
|
|
2469
|
-
exports.
|
|
2541
|
+
var runner_install_1 = require_runner_install();
|
|
2542
|
+
exports.RUNNER_REGISTRATION_TOKEN_HEADER = "x-runveric-runner-registration-token";
|
|
2543
|
+
exports.RUNNER_CREDENTIAL_HEADER = "x-runveric-runner-credential";
|
|
2544
|
+
exports.RUNNER_AUTHORIZATION_TOKEN_HEADER = "x-runveric-runner-authorization";
|
|
2470
2545
|
exports.RUNNER_POOL_ACCEPTS_PROVENANCE_BY_DEFAULT = {
|
|
2471
2546
|
// Imported from a Git source this tenant connected. Still not accepted by default: a pool
|
|
2472
2547
|
// is a machine inside a customer's network, and nothing about it is implied by connecting a
|
|
@@ -2486,7 +2561,7 @@ var require_runners = __commonJS({
|
|
|
2486
2561
|
}
|
|
2487
2562
|
__name(poolAcceptsProvenance, "poolAcceptsProvenance");
|
|
2488
2563
|
function containerNameFor(runnerName) {
|
|
2489
|
-
return
|
|
2564
|
+
return `${runner_install_1.RUNNER_CONTAINER_PREFIX}${runnerName.trim()}`;
|
|
2490
2565
|
}
|
|
2491
2566
|
__name(containerNameFor, "containerNameFor");
|
|
2492
2567
|
exports.RUNNER_LIFECYCLES = [
|
|
@@ -3309,7 +3384,7 @@ var require_workspace_domain = __commonJS({
|
|
|
3309
3384
|
"challenge_expired",
|
|
3310
3385
|
"held_elsewhere"
|
|
3311
3386
|
];
|
|
3312
|
-
exports.DOMAIN_VERIFICATION_RECORD_PREFIX = "
|
|
3387
|
+
exports.DOMAIN_VERIFICATION_RECORD_PREFIX = "runveric-domain-verification=";
|
|
3313
3388
|
function domainVerificationRecord(domain, token) {
|
|
3314
3389
|
return {
|
|
3315
3390
|
name: domain,
|
|
@@ -3516,6 +3591,8 @@ var require_dist = __commonJS({
|
|
|
3516
3591
|
__exportStar(require_package_egress(), exports);
|
|
3517
3592
|
__exportStar(require_package_execution(), exports);
|
|
3518
3593
|
__exportStar(require_runner_confinement(), exports);
|
|
3594
|
+
__exportStar(require_runner_install(), exports);
|
|
3595
|
+
__exportStar(require_authoring_cli(), exports);
|
|
3519
3596
|
__exportStar(require_runners(), exports);
|
|
3520
3597
|
__exportStar(require_runner_pool_presence(), exports);
|
|
3521
3598
|
__exportStar(require_routable_target(), exports);
|
|
@@ -3670,6 +3747,7 @@ var require_manifest_schema = __commonJS({
|
|
|
3670
3747
|
return contracts_1.RISK_LEVELS;
|
|
3671
3748
|
}, "get")
|
|
3672
3749
|
});
|
|
3750
|
+
var contracts_2 = require_dist();
|
|
3673
3751
|
exports.MANIFEST_FIELDS = [
|
|
3674
3752
|
"apiVersion",
|
|
3675
3753
|
"id",
|
|
@@ -3695,7 +3773,7 @@ var require_manifest_schema = __commonJS({
|
|
|
3695
3773
|
"secrets",
|
|
3696
3774
|
"credentialScopes",
|
|
3697
3775
|
"license",
|
|
3698
|
-
"
|
|
3776
|
+
"minRunvericVersion"
|
|
3699
3777
|
];
|
|
3700
3778
|
exports.PACKAGE_ID_PATTERN = /^[a-z0-9-]+\/[a-z0-9-]+$/;
|
|
3701
3779
|
exports.SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
@@ -3708,12 +3786,18 @@ var require_manifest_schema = __commonJS({
|
|
|
3708
3786
|
"properties",
|
|
3709
3787
|
"required",
|
|
3710
3788
|
"additionalProperties",
|
|
3711
|
-
//
|
|
3789
|
+
// Our own annotation, carried INSIDE the schema it orders rather than in a second
|
|
3712
3790
|
// column: the two would otherwise separate, and a schema whose order lives elsewhere is a
|
|
3713
3791
|
// schema that renders in the wrong order the first time one of them is copied without the
|
|
3714
3792
|
// other. Allowed here so a normalized schema round-trips through this validator rather than
|
|
3715
3793
|
// being rejected as an unknown field.
|
|
3716
|
-
|
|
3794
|
+
//
|
|
3795
|
+
// ⛔ THIS LIST IS A REJECT-UNKNOWN ALLOWLIST. `x-opera-order` left it LAST in docs/108 —
|
|
3796
|
+
// after the writer stopped stamping it, 0089 stripped it from every row, and the readers
|
|
3797
|
+
// stopped reading it. Nothing re-validates a STORED schema (every caller of this validator
|
|
3798
|
+
// is handed authored bytes), so the order was safe; an author's file that still carries the
|
|
3799
|
+
// retired key is now refused by name, as any unknown field is.
|
|
3800
|
+
contracts_2.PARAMETER_ORDER_KEY
|
|
3717
3801
|
];
|
|
3718
3802
|
exports.PARAMETER_PROPERTY_FIELDS = [
|
|
3719
3803
|
"type",
|
|
@@ -3814,7 +3898,7 @@ var require_manifest_validator = __commonJS({
|
|
|
3814
3898
|
});
|
|
3815
3899
|
validateCredentialScopes(value.credentialScopes, errors);
|
|
3816
3900
|
requiredString(value, "license", errors, manifest_schema_1.SPDX_ID_PATTERN, "an SPDX identifier");
|
|
3817
|
-
requiredString(value, "
|
|
3901
|
+
requiredString(value, "minRunvericVersion", errors, manifest_schema_1.SEMVER_PATTERN, "MAJOR.MINOR.PATCH");
|
|
3818
3902
|
return errors.length === 0 && runtime !== void 0 ? {
|
|
3819
3903
|
ok: true,
|
|
3820
3904
|
// The normalized runtime replaces the authored one, exactly as `discover` ids are
|
|
@@ -3853,7 +3937,7 @@ var require_manifest_validator = __commonJS({
|
|
|
3853
3937
|
const declaredType = validateParameterProperty(name, property, errors);
|
|
3854
3938
|
normalizedProperties[name] = isRecord(property) ? validateDiscoveryAnnotations(name, property, declaredType, value.properties, declarationOrder, context?.providers, errors, warnings) : property;
|
|
3855
3939
|
}
|
|
3856
|
-
validateParameterOrder(value[
|
|
3940
|
+
validateParameterOrder(value[contracts_1.PARAMETER_ORDER_KEY], contracts_1.PARAMETER_ORDER_KEY, declarationOrder, errors);
|
|
3857
3941
|
}
|
|
3858
3942
|
if (!Array.isArray(value.required) || !value.required.every(isString)) {
|
|
3859
3943
|
add(errors, "parameters.required", "Expected an array of property names.", "type");
|
|
@@ -4153,9 +4237,9 @@ var require_manifest_validator = __commonJS({
|
|
|
4153
4237
|
}
|
|
4154
4238
|
}
|
|
4155
4239
|
__name(validateDependency, "validateDependency");
|
|
4156
|
-
function validateParameterOrder(value, declarationOrder, errors) {
|
|
4240
|
+
function validateParameterOrder(value, key, declarationOrder, errors) {
|
|
4157
4241
|
if (value === void 0) return;
|
|
4158
|
-
const path =
|
|
4242
|
+
const path = `parameters.${key}`;
|
|
4159
4243
|
if (!Array.isArray(value) || !value.every(isString)) {
|
|
4160
4244
|
add(errors, path, "Expected an array of property names.", "type");
|
|
4161
4245
|
return;
|
|
@@ -5086,7 +5170,7 @@ var require_authoring_lint = __commonJS({
|
|
|
5086
5170
|
".sh",
|
|
5087
5171
|
".py"
|
|
5088
5172
|
];
|
|
5089
|
-
var RESULT_FILE_VARIABLE = "
|
|
5173
|
+
var RESULT_FILE_VARIABLE = "RUNVERIC_RESULT_FILE";
|
|
5090
5174
|
var ENTRYPOINT_PHASES = [
|
|
5091
5175
|
{
|
|
5092
5176
|
field: "entrypoint",
|
|
@@ -5675,7 +5759,7 @@ summary: ${yamlString(`${input.name} \u2014 describe in one line what an operato
|
|
|
5675
5759
|
category: compute
|
|
5676
5760
|
providers:
|
|
5677
5761
|
- azure
|
|
5678
|
-
connectorKey:
|
|
5762
|
+
connectorKey: ${contracts_1.PACKAGE_RUNNER_CONNECTOR_KEY}
|
|
5679
5763
|
|
|
5680
5764
|
# \u2500\u2500 How it runs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5681
5765
|
runtime:
|
|
@@ -5715,7 +5799,7 @@ secrets: []
|
|
|
5715
5799
|
|
|
5716
5800
|
# \u2500\u2500 Publishing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5717
5801
|
license: MIT
|
|
5718
|
-
|
|
5802
|
+
minRunvericVersion: 1.0.0
|
|
5719
5803
|
`;
|
|
5720
5804
|
}
|
|
5721
5805
|
__name(manifest, "manifest");
|
|
@@ -5752,12 +5836,12 @@ minOperaVersion: 1.0.0
|
|
|
5752
5836
|
return `# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5753
5837
|
# OPERA'S WRAPPER. This file is the CONTRACT; ${bodyPath} is YOURS.
|
|
5754
5838
|
#
|
|
5755
|
-
# ${contracts_1.BRAND_SHORT_NAME} reads exactly one thing from a package: the JSON at ${sigil}
|
|
5839
|
+
# ${contracts_1.BRAND_SHORT_NAME} reads exactly one thing from a package: the JSON at ${sigil}RUNVERIC_RESULT_FILE. A script
|
|
5756
5840
|
# that exits 0 without writing one has reported nothing, and ${contracts_1.BRAND_SHORT_NAME} says so rather than inventing
|
|
5757
5841
|
# a result. This file is what makes that impossible to get wrong by accident:
|
|
5758
5842
|
#
|
|
5759
5843
|
# * it starts ${bodyPath} \u2014 your script, unchanged;
|
|
5760
|
-
# * if your script wrote ${sigil}
|
|
5844
|
+
# * if your script wrote ${sigil}RUNVERIC_RESULT_FILE itself, this file leaves it exactly alone;
|
|
5761
5845
|
# * otherwise it writes one for you \u2014 succeeded when your script exits 0, failed with the exit
|
|
5762
5846
|
# code and a result.error when it does not \u2014 carrying whatever your script printed as the
|
|
5763
5847
|
# message.
|
|
@@ -5768,21 +5852,21 @@ minOperaVersion: 1.0.0
|
|
|
5768
5852
|
# WHERE YOUR SCRIPT RUNS. This file moves to the PACKAGE ROOT before starting yours, so a
|
|
5769
5853
|
# relative path in your script means what it meant on your laptop \u2014 \`source ./lib/util.sh\` and
|
|
5770
5854
|
# \`. ./lib/helpers.ps1\` resolve against the package, not against wherever the runner happened
|
|
5771
|
-
# to start. The package root is READ-ONLY and NON-EXECUTABLE: write to ${sigil}
|
|
5855
|
+
# to start. The package root is READ-ONLY and NON-EXECUTABLE: write to ${sigil}RUNVERIC_WORK_DIR,
|
|
5772
5856
|
# and call another script through your interpreter (\`bash ./tool.sh\`) rather than executing it
|
|
5773
|
-
# directly. ${sigil}
|
|
5857
|
+
# directly. ${sigil}RUNVERIC_PACKAGE_ROOT is exported so your script can be explicit rather than
|
|
5774
5858
|
# assume.
|
|
5775
5859
|
#
|
|
5776
5860
|
# THE CONTRACT (docs/22), identical in every language:
|
|
5777
|
-
# ${sigil}
|
|
5778
|
-
# ${sigil}
|
|
5779
|
-
# ${sigil}
|
|
5780
|
-
# ${sigil}
|
|
5861
|
+
# ${sigil}RUNVERIC_PARAMETERS_FILE the operator's answers, as JSON
|
|
5862
|
+
# ${sigil}RUNVERIC_CONTEXT_FILE non-secret run metadata (execution id, provider, scope)
|
|
5863
|
+
# ${sigil}RUNVERIC_RESULT_FILE where the result is WRITTEN \u2014 the only result channel
|
|
5864
|
+
# ${sigil}RUNVERIC_DRY_RUN "true" when the operator asked for a rehearsal. PASSED
|
|
5781
5865
|
# THROUGH, never acted on here: only your script knows which of
|
|
5782
5866
|
# its steps change anything.
|
|
5783
|
-
# ${sigil}
|
|
5784
|
-
# ${sigil}
|
|
5785
|
-
# Anything printed to stdout becomes a log line. A line starting with
|
|
5867
|
+
# ${sigil}RUNVERIC_WORK_DIR scratch space; nothing else is writable
|
|
5868
|
+
# ${sigil}RUNVERIC_PACKAGE_ROOT this package's root, and the working directory
|
|
5869
|
+
# Anything printed to stdout becomes a log line. A line starting with RUNVERIC_EVENT becomes a
|
|
5786
5870
|
# structured event.
|
|
5787
5871
|
#
|
|
5788
5872
|
# The runner starts run/${entryFile} the same way this file starts ${bodyPath}.
|
|
@@ -5829,7 +5913,7 @@ $ErrorActionPreference = 'Continue'
|
|
|
5829
5913
|
# setting only the first is a classic way to get a script that resolves paths differently from
|
|
5830
5914
|
# the tools it calls.
|
|
5831
5915
|
$operaPackageRoot = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..')).Path
|
|
5832
|
-
$env:
|
|
5916
|
+
$env:RUNVERIC_PACKAGE_ROOT = $operaPackageRoot
|
|
5833
5917
|
Set-Location -LiteralPath $operaPackageRoot
|
|
5834
5918
|
[Environment]::CurrentDirectory = $operaPackageRoot
|
|
5835
5919
|
|
|
@@ -5846,7 +5930,7 @@ $operaCaptured = [System.Collections.Generic.List[string]]::new()
|
|
|
5846
5930
|
|
|
5847
5931
|
# \u2500\u2500\u2500 THE OPERATOR'S ANSWERS, BOUND TO YOUR OWN param() BLOCK \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5848
5932
|
#
|
|
5849
|
-
# ${contracts_1.BRAND_SHORT_NAME} delivers the operator's answers as JSON at $env:
|
|
5933
|
+
# ${contracts_1.BRAND_SHORT_NAME} delivers the operator's answers as JSON at $env:RUNVERIC_PARAMETERS_FILE. A script written
|
|
5850
5934
|
# outside ${contracts_1.BRAND_SHORT_NAME} receives its values through its param() block. THOSE ARE DIFFERENT MECHANISMS,
|
|
5851
5935
|
# and nothing joins them unless this file does \u2014 so without the lines below a run form built from
|
|
5852
5936
|
# a param() block would collect six answers and hand your script none of them.
|
|
@@ -5865,7 +5949,7 @@ $operaCaptured = [System.Collections.Generic.List[string]]::new()
|
|
|
5865
5949
|
#
|
|
5866
5950
|
# An answer your script does not declare is IGNORED, not an error \u2014 your script is the authority
|
|
5867
5951
|
# on what it takes. A script with no param() block gets no arguments at all and reads
|
|
5868
|
-
# $env:
|
|
5952
|
+
# $env:RUNVERIC_PARAMETERS_FILE itself, exactly as before.
|
|
5869
5953
|
$operaDeclared = @()
|
|
5870
5954
|
try {
|
|
5871
5955
|
$operaTokens = $null
|
|
@@ -5884,10 +5968,10 @@ try {
|
|
|
5884
5968
|
}
|
|
5885
5969
|
|
|
5886
5970
|
$operaArguments = @()
|
|
5887
|
-
if ($operaDeclared.Count -gt 0 -and (Test-Path -LiteralPath $env:
|
|
5971
|
+
if ($operaDeclared.Count -gt 0 -and (Test-Path -LiteralPath $env:RUNVERIC_PARAMETERS_FILE)) {
|
|
5888
5972
|
$operaAnswers = $null
|
|
5889
5973
|
try {
|
|
5890
|
-
$operaAnswers = Get-Content -LiteralPath $env:
|
|
5974
|
+
$operaAnswers = Get-Content -LiteralPath $env:RUNVERIC_PARAMETERS_FILE -Raw | ConvertFrom-Json
|
|
5891
5975
|
} catch {
|
|
5892
5976
|
$operaAnswers = $null
|
|
5893
5977
|
}
|
|
@@ -5939,8 +6023,8 @@ $operaStatus = $LASTEXITCODE
|
|
|
5939
6023
|
|
|
5940
6024
|
# THE BODY'S OWN RESULT WINS. The wrapper fills a gap; it never overwrites what an author
|
|
5941
6025
|
# reported for themselves \u2014 outputs, checks and rollbackCapture all arrive this way.
|
|
5942
|
-
$operaWritten = (Test-Path -LiteralPath $env:
|
|
5943
|
-
((Get-Item -LiteralPath $env:
|
|
6026
|
+
$operaWritten = (Test-Path -LiteralPath $env:RUNVERIC_RESULT_FILE) -and
|
|
6027
|
+
((Get-Item -LiteralPath $env:RUNVERIC_RESULT_FILE).Length -gt 0)
|
|
5944
6028
|
if (-not $operaWritten) {
|
|
5945
6029
|
$operaOutput = ($operaCaptured -join "\`n").Trim()
|
|
5946
6030
|
# result.message is bounded at 4096 characters. Keep the TAIL, which is where a failure says
|
|
@@ -5965,7 +6049,7 @@ if (-not $operaWritten) {
|
|
|
5965
6049
|
}
|
|
5966
6050
|
}
|
|
5967
6051
|
}
|
|
5968
|
-
$operaResult | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $env:
|
|
6052
|
+
$operaResult | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $env:RUNVERIC_RESULT_FILE -Encoding utf8
|
|
5969
6053
|
}
|
|
5970
6054
|
|
|
5971
6055
|
# The body's exit code is this package's exit code. ${contracts_1.BRAND_SHORT_NAME} cross-checks the two \u2014 a result that
|
|
@@ -5981,16 +6065,16 @@ exit $operaStatus
|
|
|
5981
6065
|
return `${wrapperHeader(interpreter, "$", bodyPath)}
|
|
5982
6066
|
# THE PACKAGE ROOT, and the working directory your script starts in \u2014 so \`source ./lib/util.sh\`
|
|
5983
6067
|
# resolves against the package rather than against the scratch directory the runner starts in.
|
|
5984
|
-
|
|
5985
|
-
export
|
|
5986
|
-
cd "\${
|
|
6068
|
+
RUNVERIC_PACKAGE_ROOT="$(cd "$(dirname "\${BASH_SOURCE[0]}")/.." && pwd)"
|
|
6069
|
+
export RUNVERIC_PACKAGE_ROOT
|
|
6070
|
+
cd "\${RUNVERIC_PACKAGE_ROOT}"
|
|
5987
6071
|
|
|
5988
6072
|
# THE ONE PLACE the author's path is written into this file. Everything below refers to the
|
|
5989
6073
|
# variable, so an entrypoint containing a quote or a \`$\` is a string here and cannot become
|
|
5990
6074
|
# syntax. The marker is how \`authoredEntrypointOf\` reads this line back \u2014 see that function.
|
|
5991
6075
|
opera_body_path=${bashLiteral(bodyPath)} # ${ENTRYPOINT_MARKER}
|
|
5992
|
-
opera_body="\${
|
|
5993
|
-
opera_capture="\${
|
|
6076
|
+
opera_body="\${RUNVERIC_PACKAGE_ROOT}/\${opera_body_path}"
|
|
6077
|
+
opera_capture="\${RUNVERIC_WORK_DIR}/.runveric-body-output"
|
|
5994
6078
|
|
|
5995
6079
|
# Both streams merged, so the transcript below is in the order the operator saw; \`tee\` keeps
|
|
5996
6080
|
# every line arriving live rather than held until the body ends. errexit is lifted for exactly
|
|
@@ -6002,17 +6086,17 @@ set -e
|
|
|
6002
6086
|
|
|
6003
6087
|
# THE BODY'S OWN RESULT WINS. The wrapper fills a gap; it never overwrites what an author
|
|
6004
6088
|
# reported for themselves \u2014 outputs, checks and rollbackCapture all arrive this way.
|
|
6005
|
-
if [ ! -s "\${
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
python3 - > "\${
|
|
6089
|
+
if [ ! -s "\${RUNVERIC_RESULT_FILE}" ]; then
|
|
6090
|
+
RUNVERIC_BODY_STATUS="\${opera_status}" RUNVERIC_BODY_CAPTURE="\${opera_capture}" \\
|
|
6091
|
+
RUNVERIC_BODY_PATH="\${opera_body_path}" \\
|
|
6092
|
+
python3 - > "\${RUNVERIC_RESULT_FILE}" <<'PY'
|
|
6009
6093
|
import json, os
|
|
6010
6094
|
|
|
6011
6095
|
${FALLBACK_RESULT_PYTHON}
|
|
6012
6096
|
|
|
6013
|
-
with open(os.environ["
|
|
6097
|
+
with open(os.environ["RUNVERIC_BODY_CAPTURE"], encoding="utf-8", errors="replace") as handle:
|
|
6014
6098
|
captured = handle.read()
|
|
6015
|
-
print(json.dumps(opera_result(int(os.environ["
|
|
6099
|
+
print(json.dumps(opera_result(int(os.environ["RUNVERIC_BODY_STATUS"]), captured, os.environ["RUNVERIC_BODY_PATH"])))
|
|
6016
6100
|
PY
|
|
6017
6101
|
fi
|
|
6018
6102
|
|
|
@@ -6037,7 +6121,7 @@ ${FALLBACK_RESULT_PYTHON}
|
|
|
6037
6121
|
# or \`import\` resolves against the package rather than against the scratch directory the runner
|
|
6038
6122
|
# starts in. os.chdir moves this process, and the body inherits it.
|
|
6039
6123
|
opera_package_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
6040
|
-
os.environ["
|
|
6124
|
+
os.environ["RUNVERIC_PACKAGE_ROOT"] = opera_package_root
|
|
6041
6125
|
os.chdir(opera_package_root)
|
|
6042
6126
|
|
|
6043
6127
|
# THE ONE PLACE the author's path is written into this file. Everything below refers to the
|
|
@@ -6064,7 +6148,7 @@ opera_status = opera_process.wait()
|
|
|
6064
6148
|
|
|
6065
6149
|
# THE BODY'S OWN RESULT WINS. The wrapper fills a gap; it never overwrites what an author
|
|
6066
6150
|
# reported for themselves \u2014 outputs, checks and rollbackCapture all arrive this way.
|
|
6067
|
-
opera_result_file = os.environ["
|
|
6151
|
+
opera_result_file = os.environ["RUNVERIC_RESULT_FILE"]
|
|
6068
6152
|
opera_written = os.path.exists(opera_result_file) and os.path.getsize(opera_result_file) > 0
|
|
6069
6153
|
if not opera_written:
|
|
6070
6154
|
with open(opera_result_file, "w", encoding="utf-8") as handle:
|
|
@@ -6084,27 +6168,27 @@ sys.exit(opera_status)
|
|
|
6084
6168
|
# from whether it exits 0 and what it printed. Anything that runs is a working action.
|
|
6085
6169
|
#
|
|
6086
6170
|
# What you are given:
|
|
6087
|
-
# $env:
|
|
6088
|
-
# $env:
|
|
6089
|
-
# $env:
|
|
6171
|
+
# $env:RUNVERIC_PARAMETERS_FILE the operator's answers, as JSON
|
|
6172
|
+
# $env:RUNVERIC_CONTEXT_FILE non-secret run metadata (execution id, provider, scope)
|
|
6173
|
+
# $env:RUNVERIC_DRY_RUN "true" when the operator asked for a rehearsal \u2014 HONOUR IT if
|
|
6090
6174
|
# anything below changes something
|
|
6091
|
-
# $env:
|
|
6175
|
+
# $env:RUNVERIC_WORK_DIR scratch space; nothing else is writable
|
|
6092
6176
|
# Anything you print becomes a log line, and becomes the run's message.
|
|
6093
6177
|
#
|
|
6094
|
-
# WHERE YOU ARE. Your script runs from the package root \u2014 $env:
|
|
6178
|
+
# WHERE YOU ARE. Your script runs from the package root \u2014 $env:RUNVERIC_PACKAGE_ROOT \u2014 so
|
|
6095
6179
|
# \`. ./lib/helpers.ps1\` resolves the way it does on your laptop. That directory is READ-ONLY
|
|
6096
|
-
# and NON-EXECUTABLE: write to $env:
|
|
6180
|
+
# and NON-EXECUTABLE: write to $env:RUNVERIC_WORK_DIR, and start another script through its
|
|
6097
6181
|
# interpreter (\`pwsh ./tool.ps1\`) rather than executing it directly.
|
|
6098
6182
|
#
|
|
6099
6183
|
# WANT MORE THAN A MESSAGE \u2014 outputs, a rollbackCapture, your own error code? Write that JSON
|
|
6100
|
-
# to $env:
|
|
6184
|
+
# to $env:RUNVERIC_RESULT_FILE yourself and the wrapper leaves it alone. run/main.ps1 says how.
|
|
6101
6185
|
|
|
6102
6186
|
Set-StrictMode -Version Latest
|
|
6103
6187
|
$ErrorActionPreference = 'Stop'
|
|
6104
6188
|
|
|
6105
|
-
$parameters = Get-Content -LiteralPath $env:
|
|
6106
|
-
$context = Get-Content -LiteralPath $env:
|
|
6107
|
-
$dryRun = $env:
|
|
6189
|
+
$parameters = Get-Content -LiteralPath $env:RUNVERIC_PARAMETERS_FILE -Raw | ConvertFrom-Json
|
|
6190
|
+
$context = Get-Content -LiteralPath $env:RUNVERIC_CONTEXT_FILE -Raw | ConvertFrom-Json
|
|
6191
|
+
$dryRun = $env:RUNVERIC_DRY_RUN -eq 'true'
|
|
6108
6192
|
|
|
6109
6193
|
# Strict mode makes reading an absent property an error rather than an empty string, so an
|
|
6110
6194
|
# optional parameter is asked for explicitly. That is the point of strict mode: the failure
|
|
@@ -6118,85 +6202,85 @@ Write-Output "Running for execution $($context.executionId)."
|
|
|
6118
6202
|
Write-Output "Note: \${note}"
|
|
6119
6203
|
|
|
6120
6204
|
if ($dryRun) {
|
|
6121
|
-
Write-Output '
|
|
6205
|
+
Write-Output 'RUNVERIC_EVENT {"level":"info","message":"Dry run \u2014 nothing was changed."}'
|
|
6122
6206
|
} else {
|
|
6123
6207
|
# Do the real work here.
|
|
6124
|
-
Write-Output '
|
|
6208
|
+
Write-Output 'RUNVERIC_EVENT {"level":"success","message":"Nothing to change yet \u2014 this is a new action."}'
|
|
6125
6209
|
}
|
|
6126
6210
|
`,
|
|
6127
6211
|
bash: `# YOUR SCRIPT. run/main.sh \u2014 ${contracts_1.BRAND_SHORT_NAME}'s wrapper \u2014 starts this file and writes the run's result
|
|
6128
6212
|
# from whether it exits 0 and what it printed. Anything that runs is a working action.
|
|
6129
6213
|
#
|
|
6130
6214
|
# What you are given:
|
|
6131
|
-
# $
|
|
6132
|
-
# $
|
|
6133
|
-
# $
|
|
6215
|
+
# $RUNVERIC_PARAMETERS_FILE the operator's answers, as JSON
|
|
6216
|
+
# $RUNVERIC_CONTEXT_FILE non-secret run metadata (execution id, provider, scope)
|
|
6217
|
+
# $RUNVERIC_DRY_RUN "true" when the operator asked for a rehearsal \u2014 HONOUR IT if
|
|
6134
6218
|
# anything below changes something
|
|
6135
|
-
# $
|
|
6219
|
+
# $RUNVERIC_WORK_DIR scratch space; nothing else is writable
|
|
6136
6220
|
# Anything you print becomes a log line, and becomes the run's message.
|
|
6137
6221
|
#
|
|
6138
|
-
# WHERE YOU ARE. Your script runs from the package root \u2014 $
|
|
6222
|
+
# WHERE YOU ARE. Your script runs from the package root \u2014 $RUNVERIC_PACKAGE_ROOT \u2014 so
|
|
6139
6223
|
# \`source ./lib/util.sh\` resolves the way it does on your laptop. That directory is READ-ONLY
|
|
6140
|
-
# and NON-EXECUTABLE: write to $
|
|
6224
|
+
# and NON-EXECUTABLE: write to $RUNVERIC_WORK_DIR, and start another script through its
|
|
6141
6225
|
# interpreter (\`bash ./tool.sh\`) rather than executing it directly.
|
|
6142
6226
|
#
|
|
6143
6227
|
# WANT MORE THAN A MESSAGE \u2014 outputs, a rollbackCapture, your own error code? Write that JSON
|
|
6144
|
-
# to $
|
|
6228
|
+
# to $RUNVERIC_RESULT_FILE yourself and the wrapper leaves it alone. run/main.sh says how.
|
|
6145
6229
|
#
|
|
6146
6230
|
# Started with \`bash -euo pipefail\`, so a failing command ends the run instead of continuing
|
|
6147
6231
|
# past it.
|
|
6148
6232
|
|
|
6149
|
-
note="$(python3 -c 'import json,os,sys; print(json.load(open(os.environ["
|
|
6150
|
-
execution_id="$(python3 -c 'import json,os,sys; print(json.load(open(os.environ["
|
|
6233
|
+
note="$(python3 -c 'import json,os,sys; print(json.load(open(os.environ["RUNVERIC_PARAMETERS_FILE"])).get("note",""))')"
|
|
6234
|
+
execution_id="$(python3 -c 'import json,os,sys; print(json.load(open(os.environ["RUNVERIC_CONTEXT_FILE"]))["executionId"])')"
|
|
6151
6235
|
|
|
6152
6236
|
echo "Running for execution \${execution_id}."
|
|
6153
6237
|
echo "Note: \${note}"
|
|
6154
6238
|
|
|
6155
|
-
if [ "\${
|
|
6156
|
-
echo '
|
|
6239
|
+
if [ "\${RUNVERIC_DRY_RUN}" = "true" ]; then
|
|
6240
|
+
echo 'RUNVERIC_EVENT {"level":"info","message":"Dry run \u2014 nothing was changed."}'
|
|
6157
6241
|
else
|
|
6158
6242
|
# Do the real work here.
|
|
6159
|
-
echo '
|
|
6243
|
+
echo 'RUNVERIC_EVENT {"level":"success","message":"Nothing to change yet \u2014 this is a new action."}'
|
|
6160
6244
|
fi
|
|
6161
6245
|
`,
|
|
6162
6246
|
python: `# YOUR SCRIPT. run/main.py \u2014 ${contracts_1.BRAND_SHORT_NAME}'s wrapper \u2014 starts this file and writes the run's result
|
|
6163
6247
|
# from whether it exits 0 and what it printed. Anything that runs is a working action.
|
|
6164
6248
|
#
|
|
6165
6249
|
# What you are given:
|
|
6166
|
-
#
|
|
6167
|
-
#
|
|
6168
|
-
#
|
|
6250
|
+
# RUNVERIC_PARAMETERS_FILE the operator's answers, as JSON
|
|
6251
|
+
# RUNVERIC_CONTEXT_FILE non-secret run metadata (execution id, provider, scope)
|
|
6252
|
+
# RUNVERIC_DRY_RUN "true" when the operator asked for a rehearsal \u2014 HONOUR IT if
|
|
6169
6253
|
# anything below changes something
|
|
6170
|
-
#
|
|
6254
|
+
# RUNVERIC_WORK_DIR scratch space; nothing else is writable
|
|
6171
6255
|
# Anything you print becomes a log line, and becomes the run's message.
|
|
6172
6256
|
#
|
|
6173
|
-
# WHERE YOU ARE. Your script runs from the package root \u2014
|
|
6257
|
+
# WHERE YOU ARE. Your script runs from the package root \u2014 RUNVERIC_PACKAGE_ROOT \u2014 so a relative
|
|
6174
6258
|
# \`open()\` or \`import\` resolves the way it does on your laptop. That directory is READ-ONLY
|
|
6175
|
-
# and NON-EXECUTABLE: write to
|
|
6259
|
+
# and NON-EXECUTABLE: write to RUNVERIC_WORK_DIR, and start another script through its interpreter
|
|
6176
6260
|
# (\`python3 ./tool.py\`) rather than executing it directly.
|
|
6177
6261
|
#
|
|
6178
6262
|
# WANT MORE THAN A MESSAGE \u2014 outputs, a rollbackCapture, your own error code? Write that JSON
|
|
6179
|
-
# to
|
|
6263
|
+
# to RUNVERIC_RESULT_FILE yourself and the wrapper leaves it alone. run/main.py says how.
|
|
6180
6264
|
|
|
6181
6265
|
import json
|
|
6182
6266
|
import os
|
|
6183
6267
|
|
|
6184
|
-
with open(os.environ["
|
|
6268
|
+
with open(os.environ["RUNVERIC_PARAMETERS_FILE"], encoding="utf-8") as handle:
|
|
6185
6269
|
parameters = json.load(handle)
|
|
6186
|
-
with open(os.environ["
|
|
6270
|
+
with open(os.environ["RUNVERIC_CONTEXT_FILE"], encoding="utf-8") as handle:
|
|
6187
6271
|
context = json.load(handle)
|
|
6188
6272
|
|
|
6189
|
-
dry_run = os.environ.get("
|
|
6273
|
+
dry_run = os.environ.get("RUNVERIC_DRY_RUN") == "true"
|
|
6190
6274
|
note = parameters.get("note", "")
|
|
6191
6275
|
|
|
6192
6276
|
print(f"Running for execution {context['executionId']}.")
|
|
6193
6277
|
print(f"Note: {note}")
|
|
6194
6278
|
|
|
6195
6279
|
if dry_run:
|
|
6196
|
-
print('
|
|
6280
|
+
print('RUNVERIC_EVENT {"level":"info","message":"Dry run \u2014 nothing was changed."}')
|
|
6197
6281
|
else:
|
|
6198
6282
|
# Do the real work here.
|
|
6199
|
-
print('
|
|
6283
|
+
print('RUNVERIC_EVENT {"level":"success","message":"Nothing to change yet \u2014 this is a new action."}')
|
|
6200
6284
|
`
|
|
6201
6285
|
};
|
|
6202
6286
|
var VALIDATE_SCRIPT = {
|
|
@@ -6209,7 +6293,7 @@ reason, you do not also need result.error.
|
|
|
6209
6293
|
|
|
6210
6294
|
Set-StrictMode -Version Latest
|
|
6211
6295
|
$ErrorActionPreference = 'Stop'
|
|
6212
|
-
$parameters = Get-Content -LiteralPath $env:
|
|
6296
|
+
$parameters = Get-Content -LiteralPath $env:RUNVERIC_PARAMETERS_FILE -Raw | ConvertFrom-Json
|
|
6213
6297
|
|
|
6214
6298
|
$checks = @(
|
|
6215
6299
|
[ordered]@{ status = 'passed'; message = 'The note is present.' }
|
|
@@ -6221,7 +6305,7 @@ $failed = @($checks | Where-Object { $_.status -eq 'failed' }).Count -gt 0
|
|
|
6221
6305
|
status = if ($failed) { 'failed' } else { 'succeeded' }
|
|
6222
6306
|
message = if ($failed) { 'Pre-flight found a blocking problem.' } else { 'Pre-flight passed.' }
|
|
6223
6307
|
checks = $checks
|
|
6224
|
-
} | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $env:
|
|
6308
|
+
} | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $env:RUNVERIC_RESULT_FILE -Encoding utf8`,
|
|
6225
6309
|
bash: `The VALIDATE phase \u2014 a pre-flight that changes nothing.
|
|
6226
6310
|
Enable it with \`validateEntrypoint: validate/\` in action.yaml, then uncomment this file.
|
|
6227
6311
|
|
|
@@ -6229,7 +6313,7 @@ A validate result carries CHECKS and no outputs. One entry per thing you checked
|
|
|
6229
6313
|
passed / warning / failed. If any check failed, set status to "failed" \u2014 the checks ARE the
|
|
6230
6314
|
reason, you do not also need result.error.
|
|
6231
6315
|
|
|
6232
|
-
python3 - <<'PY' > "\${
|
|
6316
|
+
python3 - <<'PY' > "\${RUNVERIC_RESULT_FILE}"
|
|
6233
6317
|
import json
|
|
6234
6318
|
checks = [{"status": "passed", "message": "The note is present."}]
|
|
6235
6319
|
failed = any(check["status"] == "failed" for check in checks)
|
|
@@ -6253,7 +6337,7 @@ import os
|
|
|
6253
6337
|
checks = [{"status": "passed", "message": "The note is present."}]
|
|
6254
6338
|
failed = any(check["status"] == "failed" for check in checks)
|
|
6255
6339
|
|
|
6256
|
-
with open(os.environ["
|
|
6340
|
+
with open(os.environ["RUNVERIC_RESULT_FILE"], "w", encoding="utf-8") as handle:
|
|
6257
6341
|
json.dump(
|
|
6258
6342
|
{
|
|
6259
6343
|
"protocolVersion": "${contracts_1.PACKAGE_RESULT_PROTOCOL_VERSION}",
|
|
@@ -6269,28 +6353,28 @@ with open(os.environ["OPERA_RESULT_FILE"], "w", encoding="utf-8") as handle:
|
|
|
6269
6353
|
Enable it by setting \`rollback: true\`, \`rollbackEntrypoint: rollback/\` and
|
|
6270
6354
|
\`capabilities.rollback: true\` in action.yaml, then uncomment this file.
|
|
6271
6355
|
|
|
6272
|
-
Rollback reads what the run phase captured, at $env:
|
|
6356
|
+
Rollback reads what the run phase captured, at $env:RUNVERIC_PRIOR_RESULT_FILE. That is why a
|
|
6273
6357
|
run that intends to be undoable writes \`rollbackCapture\` into its result \u2014 this phase has
|
|
6274
6358
|
nothing else to work from.
|
|
6275
6359
|
|
|
6276
6360
|
Set-StrictMode -Version Latest
|
|
6277
6361
|
$ErrorActionPreference = 'Stop'
|
|
6278
|
-
$prior = Get-Content -LiteralPath $env:
|
|
6362
|
+
$prior = Get-Content -LiteralPath $env:RUNVERIC_PRIOR_RESULT_FILE -Raw | ConvertFrom-Json
|
|
6279
6363
|
|
|
6280
6364
|
[ordered]@{
|
|
6281
6365
|
protocolVersion = '${contracts_1.PACKAGE_RESULT_PROTOCOL_VERSION}'
|
|
6282
6366
|
status = 'succeeded'
|
|
6283
6367
|
message = 'Rolled back.'
|
|
6284
|
-
} | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $env:
|
|
6368
|
+
} | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $env:RUNVERIC_RESULT_FILE -Encoding utf8`,
|
|
6285
6369
|
bash: `The ROLLBACK phase \u2014 undo what the run phase did.
|
|
6286
6370
|
Enable it by setting \`rollback: true\`, \`rollbackEntrypoint: rollback/\` and
|
|
6287
6371
|
\`capabilities.rollback: true\` in action.yaml, then uncomment this file.
|
|
6288
6372
|
|
|
6289
|
-
Rollback reads what the run phase captured, at $
|
|
6373
|
+
Rollback reads what the run phase captured, at $RUNVERIC_PRIOR_RESULT_FILE. That is why a run
|
|
6290
6374
|
that intends to be undoable writes \`rollbackCapture\` into its result \u2014 this phase has
|
|
6291
6375
|
nothing else to work from.
|
|
6292
6376
|
|
|
6293
|
-
python3 - <<'PY' > "\${
|
|
6377
|
+
python3 - <<'PY' > "\${RUNVERIC_RESULT_FILE}"
|
|
6294
6378
|
import json
|
|
6295
6379
|
print(json.dumps({
|
|
6296
6380
|
"protocolVersion": "${contracts_1.PACKAGE_RESULT_PROTOCOL_VERSION}",
|
|
@@ -6302,17 +6386,17 @@ PY`,
|
|
|
6302
6386
|
Enable it by setting \`rollback: true\`, \`rollbackEntrypoint: rollback/\` and
|
|
6303
6387
|
\`capabilities.rollback: true\` in action.yaml, then uncomment this file.
|
|
6304
6388
|
|
|
6305
|
-
Rollback reads what the run phase captured, at
|
|
6389
|
+
Rollback reads what the run phase captured, at RUNVERIC_PRIOR_RESULT_FILE. That is why a run
|
|
6306
6390
|
that intends to be undoable writes \`rollbackCapture\` into its result \u2014 this phase has
|
|
6307
6391
|
nothing else to work from.
|
|
6308
6392
|
|
|
6309
6393
|
import json
|
|
6310
6394
|
import os
|
|
6311
6395
|
|
|
6312
|
-
with open(os.environ["
|
|
6396
|
+
with open(os.environ["RUNVERIC_PRIOR_RESULT_FILE"], encoding="utf-8") as handle:
|
|
6313
6397
|
prior = json.load(handle)
|
|
6314
6398
|
|
|
6315
|
-
with open(os.environ["
|
|
6399
|
+
with open(os.environ["RUNVERIC_RESULT_FILE"], "w", encoding="utf-8") as handle:
|
|
6316
6400
|
json.dump(
|
|
6317
6401
|
{
|
|
6318
6402
|
"protocolVersion": "${contracts_1.PACKAGE_RESULT_PROTOCOL_VERSION}",
|
|
@@ -6339,7 +6423,7 @@ point of it is that the loop below works before you have written anything.
|
|
|
6339
6423
|
|
|
6340
6424
|
**\`run/${bodyFile}\` is your script. \`run/${entryFile}\` is ${contracts_1.BRAND_SHORT_NAME}'s wrapper.**
|
|
6341
6425
|
|
|
6342
|
-
${contracts_1.BRAND_SHORT_NAME} reads exactly one thing from a package: the JSON at \`
|
|
6426
|
+
${contracts_1.BRAND_SHORT_NAME} reads exactly one thing from a package: the JSON at \`RUNVERIC_RESULT_FILE\`. A package that
|
|
6343
6427
|
exits 0 without writing one has reported nothing, and ${contracts_1.BRAND_SHORT_NAME} refuses it rather than inventing a
|
|
6344
6428
|
result \u2014 that strictness is what makes every check, output and rollback capture in the product
|
|
6345
6429
|
worth trusting.
|
|
@@ -6347,7 +6431,7 @@ worth trusting.
|
|
|
6347
6431
|
\`run/${entryFile}\` is what keeps you on the right side of it. It starts \`run/${bodyFile}\`,
|
|
6348
6432
|
and then:
|
|
6349
6433
|
|
|
6350
|
-
- if your script wrote \`
|
|
6434
|
+
- if your script wrote \`RUNVERIC_RESULT_FILE\` itself, it leaves that result exactly alone;
|
|
6351
6435
|
- otherwise it writes one \u2014 **succeeded** when your script exits 0, **failed** with the exit
|
|
6352
6436
|
code and a \`result.error\` when it does not \u2014 carrying whatever your script printed as the
|
|
6353
6437
|
message.
|
|
@@ -6410,14 +6494,14 @@ script and reports the result.
|
|
|
6410
6494
|
|
|
6411
6495
|
## The result contract, and why the wrapper is there
|
|
6412
6496
|
|
|
6413
|
-
${contracts_1.BRAND_SHORT_NAME} reads exactly one thing from a package: the JSON at \`
|
|
6497
|
+
${contracts_1.BRAND_SHORT_NAME} reads exactly one thing from a package: the JSON at \`RUNVERIC_RESULT_FILE\`. A package that
|
|
6414
6498
|
exits 0 without writing one has reported nothing, and ${contracts_1.BRAND_SHORT_NAME} refuses it rather than inventing a
|
|
6415
6499
|
result \u2014 that strictness is what makes every check, output and rollback capture in the product
|
|
6416
6500
|
worth trusting.
|
|
6417
6501
|
|
|
6418
6502
|
\`run/${entryFile}\` keeps you on the right side of it. It starts \`${input.entrypoint}\`, and then:
|
|
6419
6503
|
|
|
6420
|
-
- if your script wrote \`
|
|
6504
|
+
- if your script wrote \`RUNVERIC_RESULT_FILE\` itself, it leaves that result exactly alone;
|
|
6421
6505
|
- otherwise it writes one \u2014 **succeeded** when your script exits 0, **failed** with the exit
|
|
6422
6506
|
code and a \`result.error\` when it does not \u2014 carrying whatever your script printed as the
|
|
6423
6507
|
message.
|
|
@@ -6426,12 +6510,12 @@ So a script that only prints something is already a complete action.
|
|
|
6426
6510
|
|
|
6427
6511
|
## Where your script runs
|
|
6428
6512
|
|
|
6429
|
-
From the **package root**, which is also \`
|
|
6513
|
+
From the **package root**, which is also \`RUNVERIC_PACKAGE_ROOT\`. That is what makes
|
|
6430
6514
|
\`source ./lib/util.sh\` and \`. ./lib/helpers.ps1\` resolve the way they do on your laptop.
|
|
6431
6515
|
|
|
6432
6516
|
Two things about that directory are worth knowing before your first run:
|
|
6433
6517
|
|
|
6434
|
-
- it is **read-only** \u2014 write to \`
|
|
6518
|
+
- it is **read-only** \u2014 write to \`RUNVERIC_WORK_DIR\`, the only writable location;
|
|
6435
6519
|
- it is **non-executable** \u2014 start another script through its interpreter
|
|
6436
6520
|
(\`bash ./tool.sh\`, \`pwsh ./tool.ps1\`) rather than executing it directly.
|
|
6437
6521
|
|
|
@@ -6486,7 +6570,7 @@ SOFTWARE.
|
|
|
6486
6570
|
}
|
|
6487
6571
|
__name(license, "license");
|
|
6488
6572
|
var GITIGNORE = `# runveric test writes its scratch here.
|
|
6489
|
-
.
|
|
6573
|
+
.runveric/
|
|
6490
6574
|
*.log
|
|
6491
6575
|
`;
|
|
6492
6576
|
function yamlString(value) {
|
|
@@ -6857,7 +6941,7 @@ var require_dist2 = __commonJS({
|
|
|
6857
6941
|
});
|
|
6858
6942
|
|
|
6859
6943
|
// package.json
|
|
6860
|
-
var version = "0.1.
|
|
6944
|
+
var version = "0.1.2";
|
|
6861
6945
|
|
|
6862
6946
|
// src/check.ts
|
|
6863
6947
|
var import_action_manifest = __toESM(require_dist2());
|
|
@@ -6868,7 +6952,7 @@ import { readdir, readFile, stat } from "fs/promises";
|
|
|
6868
6952
|
import { join, relative, sep } from "path";
|
|
6869
6953
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
6870
6954
|
".git",
|
|
6871
|
-
".
|
|
6955
|
+
".runveric",
|
|
6872
6956
|
"node_modules",
|
|
6873
6957
|
".venv",
|
|
6874
6958
|
"__pycache__",
|
|
@@ -7175,14 +7259,32 @@ __name(titleCase, "titleCase");
|
|
|
7175
7259
|
var import_action_manifest3 = __toESM(require_dist2());
|
|
7176
7260
|
var import_contracts3 = __toESM(require_dist());
|
|
7177
7261
|
import { resolve as resolve3 } from "path";
|
|
7178
|
-
|
|
7179
|
-
|
|
7262
|
+
|
|
7263
|
+
// src/renamed-variable.ts
|
|
7264
|
+
function renamedVariableRefusal(current, retired, env = process.env) {
|
|
7265
|
+
if (env[current]?.trim()) return null;
|
|
7266
|
+
if (!env[retired]?.trim()) return null;
|
|
7267
|
+
return `${retired} is set, but this CLI reads ${current} \u2014 the variable was renamed in 0.1.2. Rename the export in your shell or CI; ${retired} is no longer read.`;
|
|
7268
|
+
}
|
|
7269
|
+
__name(renamedVariableRefusal, "renamedVariableRefusal");
|
|
7270
|
+
|
|
7271
|
+
// src/publish.ts
|
|
7272
|
+
var TOKEN_ENV = import_contracts3.AUTHORING_CLI_ENV.token;
|
|
7273
|
+
var URL_ENV = import_contracts3.AUTHORING_CLI_ENV.url;
|
|
7180
7274
|
async function runPublish(options) {
|
|
7181
7275
|
const directory = resolve3(options.directory ?? ".");
|
|
7182
7276
|
const baseUrl = (options.to ?? process.env[URL_ENV] ?? "").trim().replace(/\/+$/, "");
|
|
7183
7277
|
const token = (options.token ?? process.env[TOKEN_ENV] ?? "").trim();
|
|
7278
|
+
const stale = [
|
|
7279
|
+
options.to === void 0 ? renamedVariableRefusal(URL_ENV, import_contracts3.RETIRED_AUTHORING_CLI_ENV.url) : null,
|
|
7280
|
+
options.token === void 0 ? renamedVariableRefusal(TOKEN_ENV, import_contracts3.RETIRED_AUTHORING_CLI_ENV.token) : null
|
|
7281
|
+
].filter((sentence) => sentence !== null);
|
|
7282
|
+
if (stale.length > 0) {
|
|
7283
|
+
for (const sentence of stale) printError(style.red(sentence));
|
|
7284
|
+
return 1;
|
|
7285
|
+
}
|
|
7184
7286
|
if (!baseUrl) {
|
|
7185
|
-
printError(style.red("Where to?") + ` Pass --to https://your-
|
|
7287
|
+
printError(style.red("Where to?") + ` Pass --to https://your-runveric.example.com, or set ${URL_ENV}.`);
|
|
7186
7288
|
return 1;
|
|
7187
7289
|
}
|
|
7188
7290
|
if (!token) {
|
|
@@ -7285,6 +7387,79 @@ function formatProblem(text) {
|
|
|
7285
7387
|
}
|
|
7286
7388
|
__name(formatProblem, "formatProblem");
|
|
7287
7389
|
|
|
7390
|
+
// src/runner-image.ts
|
|
7391
|
+
var import_contracts4 = __toESM(require_dist());
|
|
7392
|
+
import { execFile } from "child_process";
|
|
7393
|
+
import { promisify } from "util";
|
|
7394
|
+
var run = promisify(execFile);
|
|
7395
|
+
var LOCAL_RUNNER_IMAGE = "runveric-package-runner:local";
|
|
7396
|
+
var RUNNER_IMAGE_ENV = import_contracts4.AUTHORING_CLI_ENV.runnerImage;
|
|
7397
|
+
var RenamedVariableError = class extends Error {
|
|
7398
|
+
static {
|
|
7399
|
+
__name(this, "RenamedVariableError");
|
|
7400
|
+
}
|
|
7401
|
+
};
|
|
7402
|
+
function resolveRunnerImage(flag) {
|
|
7403
|
+
const explicit = flag?.trim();
|
|
7404
|
+
if (explicit) return {
|
|
7405
|
+
reference: explicit,
|
|
7406
|
+
origin: "flag"
|
|
7407
|
+
};
|
|
7408
|
+
const configured = process.env[RUNNER_IMAGE_ENV]?.trim();
|
|
7409
|
+
if (configured) return {
|
|
7410
|
+
reference: configured,
|
|
7411
|
+
origin: "environment"
|
|
7412
|
+
};
|
|
7413
|
+
const stale = renamedVariableRefusal(RUNNER_IMAGE_ENV, import_contracts4.RETIRED_AUTHORING_CLI_ENV.runnerImage);
|
|
7414
|
+
if (stale) throw new RenamedVariableError(stale);
|
|
7415
|
+
return {
|
|
7416
|
+
reference: LOCAL_RUNNER_IMAGE,
|
|
7417
|
+
origin: "local-build"
|
|
7418
|
+
};
|
|
7419
|
+
}
|
|
7420
|
+
__name(resolveRunnerImage, "resolveRunnerImage");
|
|
7421
|
+
function runnerImageNote(image) {
|
|
7422
|
+
switch (image.origin) {
|
|
7423
|
+
case "flag":
|
|
7424
|
+
return "from --image";
|
|
7425
|
+
case "environment":
|
|
7426
|
+
return `from ${RUNNER_IMAGE_ENV}`;
|
|
7427
|
+
case "local-build":
|
|
7428
|
+
return `locally built \u2014 NOT the image your ${import_contracts4.BRAND_SHORT_NAME} runs; set ${RUNNER_IMAGE_ENV} to match it`;
|
|
7429
|
+
}
|
|
7430
|
+
}
|
|
7431
|
+
__name(runnerImageNote, "runnerImageNote");
|
|
7432
|
+
var DockerMissingError = class extends Error {
|
|
7433
|
+
static {
|
|
7434
|
+
__name(this, "DockerMissingError");
|
|
7435
|
+
}
|
|
7436
|
+
};
|
|
7437
|
+
async function assertDockerAvailable() {
|
|
7438
|
+
try {
|
|
7439
|
+
await run("docker", [
|
|
7440
|
+
"version",
|
|
7441
|
+
"--format",
|
|
7442
|
+
"{{.Server.Version}}"
|
|
7443
|
+
]);
|
|
7444
|
+
} catch {
|
|
7445
|
+
throw new DockerMissingError(`Docker is not available. \`runveric test\` runs your package in the real ${import_contracts4.BRAND_SHORT_NAME} runner image, which needs a container runtime \u2014 install Docker Desktop (or start it), then try again. \`runveric check\` needs nothing and still works.`);
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
__name(assertDockerAvailable, "assertDockerAvailable");
|
|
7449
|
+
async function imageIsPresent(reference) {
|
|
7450
|
+
try {
|
|
7451
|
+
await run("docker", [
|
|
7452
|
+
"image",
|
|
7453
|
+
"inspect",
|
|
7454
|
+
reference
|
|
7455
|
+
]);
|
|
7456
|
+
return true;
|
|
7457
|
+
} catch {
|
|
7458
|
+
return false;
|
|
7459
|
+
}
|
|
7460
|
+
}
|
|
7461
|
+
__name(imageIsPresent, "imageIsPresent");
|
|
7462
|
+
|
|
7288
7463
|
// src/test.ts
|
|
7289
7464
|
var import_action_manifest4 = __toESM(require_dist2());
|
|
7290
7465
|
import { spawn } from "child_process";
|
|
@@ -7294,9 +7469,9 @@ import { dirname as dirname2, join as join3, resolve as resolve4 } from "path";
|
|
|
7294
7469
|
import { StringDecoder } from "string_decoder";
|
|
7295
7470
|
|
|
7296
7471
|
// src/azure-credential.ts
|
|
7297
|
-
import { execFile } from "child_process";
|
|
7298
|
-
import { promisify } from "util";
|
|
7299
|
-
var
|
|
7472
|
+
import { execFile as execFile2 } from "child_process";
|
|
7473
|
+
import { promisify as promisify2 } from "util";
|
|
7474
|
+
var run2 = promisify2(execFile2);
|
|
7300
7475
|
var AzureCredentialError = class extends Error {
|
|
7301
7476
|
static {
|
|
7302
7477
|
__name(this, "AzureCredentialError");
|
|
@@ -7343,7 +7518,7 @@ __name(acquireAzureCredential, "acquireAzureCredential");
|
|
|
7343
7518
|
async function azJson(args) {
|
|
7344
7519
|
let stdout;
|
|
7345
7520
|
try {
|
|
7346
|
-
({ stdout } = await
|
|
7521
|
+
({ stdout } = await run2("az", args, {
|
|
7347
7522
|
maxBuffer: 8 * 1024 * 1024
|
|
7348
7523
|
}));
|
|
7349
7524
|
} catch (error) {
|
|
@@ -7359,72 +7534,6 @@ ${message.trim()}`);
|
|
|
7359
7534
|
}
|
|
7360
7535
|
__name(azJson, "azJson");
|
|
7361
7536
|
|
|
7362
|
-
// src/runner-image.ts
|
|
7363
|
-
var import_contracts4 = __toESM(require_dist());
|
|
7364
|
-
import { execFile as execFile2 } from "child_process";
|
|
7365
|
-
import { promisify as promisify2 } from "util";
|
|
7366
|
-
var run2 = promisify2(execFile2);
|
|
7367
|
-
var LOCAL_RUNNER_IMAGE = "opera-package-runner:local";
|
|
7368
|
-
var RUNNER_IMAGE_ENV = "OPERA_RUNNER_IMAGE";
|
|
7369
|
-
function resolveRunnerImage(flag) {
|
|
7370
|
-
const explicit = flag?.trim();
|
|
7371
|
-
if (explicit) return {
|
|
7372
|
-
reference: explicit,
|
|
7373
|
-
origin: "flag"
|
|
7374
|
-
};
|
|
7375
|
-
const configured = process.env[RUNNER_IMAGE_ENV]?.trim();
|
|
7376
|
-
if (configured) return {
|
|
7377
|
-
reference: configured,
|
|
7378
|
-
origin: "environment"
|
|
7379
|
-
};
|
|
7380
|
-
return {
|
|
7381
|
-
reference: LOCAL_RUNNER_IMAGE,
|
|
7382
|
-
origin: "local-build"
|
|
7383
|
-
};
|
|
7384
|
-
}
|
|
7385
|
-
__name(resolveRunnerImage, "resolveRunnerImage");
|
|
7386
|
-
function runnerImageNote(image) {
|
|
7387
|
-
switch (image.origin) {
|
|
7388
|
-
case "flag":
|
|
7389
|
-
return "from --image";
|
|
7390
|
-
case "environment":
|
|
7391
|
-
return `from ${RUNNER_IMAGE_ENV}`;
|
|
7392
|
-
case "local-build":
|
|
7393
|
-
return `locally built \u2014 NOT the image your ${import_contracts4.BRAND_SHORT_NAME} runs; set OPERA_RUNNER_IMAGE to match it`;
|
|
7394
|
-
}
|
|
7395
|
-
}
|
|
7396
|
-
__name(runnerImageNote, "runnerImageNote");
|
|
7397
|
-
var DockerMissingError = class extends Error {
|
|
7398
|
-
static {
|
|
7399
|
-
__name(this, "DockerMissingError");
|
|
7400
|
-
}
|
|
7401
|
-
};
|
|
7402
|
-
async function assertDockerAvailable() {
|
|
7403
|
-
try {
|
|
7404
|
-
await run2("docker", [
|
|
7405
|
-
"version",
|
|
7406
|
-
"--format",
|
|
7407
|
-
"{{.Server.Version}}"
|
|
7408
|
-
]);
|
|
7409
|
-
} catch {
|
|
7410
|
-
throw new DockerMissingError(`Docker is not available. \`runveric test\` runs your package in the real ${import_contracts4.BRAND_SHORT_NAME} runner image, which needs a container runtime \u2014 install Docker Desktop (or start it), then try again. \`runveric check\` needs nothing and still works.`);
|
|
7411
|
-
}
|
|
7412
|
-
}
|
|
7413
|
-
__name(assertDockerAvailable, "assertDockerAvailable");
|
|
7414
|
-
async function imageIsPresent(reference) {
|
|
7415
|
-
try {
|
|
7416
|
-
await run2("docker", [
|
|
7417
|
-
"image",
|
|
7418
|
-
"inspect",
|
|
7419
|
-
reference
|
|
7420
|
-
]);
|
|
7421
|
-
return true;
|
|
7422
|
-
} catch {
|
|
7423
|
-
return false;
|
|
7424
|
-
}
|
|
7425
|
-
}
|
|
7426
|
-
__name(imageIsPresent, "imageIsPresent");
|
|
7427
|
-
|
|
7428
7537
|
// src/test.ts
|
|
7429
7538
|
var import_contracts5 = __toESM(require_dist());
|
|
7430
7539
|
var PHASES = [
|
|
@@ -7433,11 +7542,11 @@ var PHASES = [
|
|
|
7433
7542
|
"rollback"
|
|
7434
7543
|
];
|
|
7435
7544
|
var CONTAINER = {
|
|
7436
|
-
packageRoot: "/
|
|
7437
|
-
input: "/
|
|
7438
|
-
output: "/
|
|
7439
|
-
scratch: "/
|
|
7440
|
-
creds: "/
|
|
7545
|
+
packageRoot: "/runveric/package",
|
|
7546
|
+
input: "/runveric/input",
|
|
7547
|
+
output: "/runveric/output",
|
|
7548
|
+
scratch: "/runveric/scratch",
|
|
7549
|
+
creds: "/runveric/creds"
|
|
7441
7550
|
};
|
|
7442
7551
|
async function runTest(options) {
|
|
7443
7552
|
const directory = resolve4(options.directory ?? ".");
|
|
@@ -7476,7 +7585,13 @@ async function runTest(options) {
|
|
|
7476
7585
|
printError(style.red(error instanceof Error ? error.message : String(error)));
|
|
7477
7586
|
return 1;
|
|
7478
7587
|
}
|
|
7479
|
-
|
|
7588
|
+
let image;
|
|
7589
|
+
try {
|
|
7590
|
+
image = resolveRunnerImage(options.image);
|
|
7591
|
+
} catch (error) {
|
|
7592
|
+
printError(style.red(error instanceof Error ? error.message : String(error)));
|
|
7593
|
+
return 1;
|
|
7594
|
+
}
|
|
7480
7595
|
try {
|
|
7481
7596
|
await assertDockerAvailable();
|
|
7482
7597
|
} catch (error) {
|
|
@@ -7515,7 +7630,7 @@ async function runTest(options) {
|
|
|
7515
7630
|
} else {
|
|
7516
7631
|
print(` network ${style.grey("none \u2014 this package declares requiresNetwork: false")}`);
|
|
7517
7632
|
}
|
|
7518
|
-
if (options.dryRun) print(` ${style.bold("dry run")}
|
|
7633
|
+
if (options.dryRun) print(` ${style.bold("dry run")} RUNVERIC_DRY_RUN=true`);
|
|
7519
7634
|
if (!await imageIsPresent(image.reference)) {
|
|
7520
7635
|
print(` ${style.grey("pulling the image (first run only)\u2026")}`);
|
|
7521
7636
|
}
|
|
@@ -7645,27 +7760,27 @@ async function runContainer(options) {
|
|
|
7645
7760
|
const launch = import_action_manifest4.PACKAGE_INTERPRETER_LAUNCH[options.interpreter];
|
|
7646
7761
|
const script = `${CONTAINER.packageRoot}/${options.entrypoint}${launch.entryFile}`;
|
|
7647
7762
|
const environment = {
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7763
|
+
RUNVERIC_PROTOCOL_VERSION: import_contracts5.PACKAGE_RESULT_PROTOCOL_VERSION,
|
|
7764
|
+
RUNVERIC_PHASE: options.phase,
|
|
7765
|
+
RUNVERIC_CONTEXT_FILE: `${CONTAINER.input}/context.json`,
|
|
7766
|
+
RUNVERIC_PARAMETERS_FILE: `${CONTAINER.input}/parameters.json`,
|
|
7767
|
+
RUNVERIC_RESULT_FILE: `${CONTAINER.output}/result.json`,
|
|
7768
|
+
RUNVERIC_WORK_DIR: CONTAINER.scratch,
|
|
7769
|
+
RUNVERIC_CANCEL_FILE: `${CONTAINER.input}/cancel.requested`,
|
|
7770
|
+
RUNVERIC_DRY_RUN: options.dryRun ? "true" : "false",
|
|
7656
7771
|
// HONEST, and matching the ACA runner's own reasoning: this flag means "there is no route
|
|
7657
7772
|
// out at all". A container with `--network none` genuinely has none; one with a network
|
|
7658
7773
|
// does not, whether or not an allowlist would have applied.
|
|
7659
|
-
|
|
7774
|
+
RUNVERIC_NETWORK_ISOLATED: options.requiresNetwork ? "false" : "true",
|
|
7660
7775
|
LANG: "C.UTF-8",
|
|
7661
7776
|
LC_ALL: "C.UTF-8",
|
|
7662
7777
|
POWERSHELL_TELEMETRY_OPTOUT: "1",
|
|
7663
7778
|
DOTNET_CLI_TELEMETRY_OPTOUT: "1",
|
|
7664
7779
|
...options.layout.hasPriorResult ? {
|
|
7665
|
-
|
|
7780
|
+
RUNVERIC_PRIOR_RESULT_FILE: `${CONTAINER.input}/prior-result.json`
|
|
7666
7781
|
} : {},
|
|
7667
7782
|
...options.layout.hasCredential ? {
|
|
7668
|
-
|
|
7783
|
+
RUNVERIC_AZURE_TOKEN_FILE: `${CONTAINER.creds}/azure-token`
|
|
7669
7784
|
} : {},
|
|
7670
7785
|
...options.credentialEnv ?? {}
|
|
7671
7786
|
};
|
|
@@ -7748,7 +7863,7 @@ async function runContainer(options) {
|
|
|
7748
7863
|
__name(runContainer, "runContainer");
|
|
7749
7864
|
function emitLine(line, stderr, onEvent) {
|
|
7750
7865
|
if (line.length === 0) return;
|
|
7751
|
-
const prefix = "
|
|
7866
|
+
const prefix = "RUNVERIC_EVENT ";
|
|
7752
7867
|
if (!stderr && line.startsWith(prefix)) {
|
|
7753
7868
|
try {
|
|
7754
7869
|
const parsed = JSON.parse(line.slice(prefix.length));
|
|
@@ -7760,7 +7875,7 @@ function emitLine(line, stderr, onEvent) {
|
|
|
7760
7875
|
}
|
|
7761
7876
|
onEvent({
|
|
7762
7877
|
level: "warn",
|
|
7763
|
-
message: "Package emitted malformed
|
|
7878
|
+
message: "Package emitted malformed RUNVERIC_EVENT JSON."
|
|
7764
7879
|
});
|
|
7765
7880
|
return;
|
|
7766
7881
|
}
|
|
@@ -7778,7 +7893,7 @@ async function reportOutcome(options) {
|
|
|
7778
7893
|
const exists = await stat2(options.resultPath).catch(() => null);
|
|
7779
7894
|
if (!exists?.isFile() || exists.size === 0) {
|
|
7780
7895
|
printError(style.red("\nThe package wrote no result.") + `
|
|
7781
|
-
result.json is the only channel ${import_contracts5.BRAND_SHORT_NAME} reads. Exiting ${options.exit.code ?? "with a signal"} without writing $
|
|
7896
|
+
result.json is the only channel ${import_contracts5.BRAND_SHORT_NAME} reads. Exiting ${options.exit.code ?? "with a signal"} without writing $RUNVERIC_RESULT_FILE is a FAILED run, whatever the script printed.
|
|
7782
7897
|
Write it as the last thing your script does, on every path \u2014 including the ones that fail.`);
|
|
7783
7898
|
return 1;
|
|
7784
7899
|
}
|
|
@@ -7853,17 +7968,17 @@ ${style.bold("check")}
|
|
|
7853
7968
|
|
|
7854
7969
|
${style.bold("test")}
|
|
7855
7970
|
--phase <name> validate | run | rollback. Defaults to run.
|
|
7856
|
-
--dry-run Sets
|
|
7971
|
+
--dry-run Sets RUNVERIC_DRY_RUN=true, as an operator's rehearsal does.
|
|
7857
7972
|
--param <name=value> A parameter value. Repeatable. Defaults come from your schema.
|
|
7858
7973
|
--params-file <path> A JSON object of parameters. --param overrides it.
|
|
7859
7974
|
--prior-result <path> The run's result.json. Required shape for --phase rollback.
|
|
7860
|
-
--image <ref> The runner image. Defaults to
|
|
7975
|
+
--image <ref> The runner image. Defaults to $${RUNNER_IMAGE_ENV}.
|
|
7861
7976
|
--no-credential Skip \`az account get-access-token\`.
|
|
7862
|
-
--keep Keep the materialized /
|
|
7977
|
+
--keep Keep the materialized /runveric tree for inspection.
|
|
7863
7978
|
|
|
7864
7979
|
${style.bold("publish")}
|
|
7865
|
-
--to <url> Your ${import_contracts6.BRAND_SHORT_NAME} URL. Defaults to
|
|
7866
|
-
--token <token> Access token. Defaults to
|
|
7980
|
+
--to <url> Your ${import_contracts6.BRAND_SHORT_NAME} URL. Defaults to $${URL_ENV}.
|
|
7981
|
+
--token <token> Access token. Defaults to $${TOKEN_ENV}.
|
|
7867
7982
|
--force Publish despite lint errors. Never bypasses ${import_contracts6.BRAND_SHORT_NAME}'s validation.
|
|
7868
7983
|
|
|
7869
7984
|
${style.bold("EVERYWHERE")}
|