@codyswann/lisa 4.70.3 → 4.71.0
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/all/copy-overwrite/scripts/lib/automation-provenance-contract.mjs +174 -0
- package/all/copy-overwrite/scripts/lib/automation-provenance-local.mjs +279 -0
- package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +17 -7
- package/all/copy-overwrite/scripts/lib/github-attestation-provider.mjs +241 -0
- package/all/copy-overwrite/scripts/lib/github-attestation-recovery.mjs +283 -0
- package/all/copy-overwrite/scripts/lib/github-attestation-verifier.mjs +244 -0
- package/all/copy-overwrite/scripts/lib/history-secret-evidence-shape.mjs +188 -0
- package/all/copy-overwrite/scripts/lib/history-secret-evidence.mjs +271 -0
- package/all/copy-overwrite/scripts/lib/history-secret-scanner.mjs +6 -296
- package/all/copy-overwrite/scripts/lib/npm-update-allocate.mjs +289 -0
- package/all/copy-overwrite/scripts/lib/npm-update-authorization.mjs +235 -0
- package/all/copy-overwrite/scripts/lib/npm-update-broker-client.mjs +92 -0
- package/all/copy-overwrite/scripts/lib/npm-update-checkpoint.mjs +241 -0
- package/all/copy-overwrite/scripts/lib/npm-update-contract.mjs +278 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-broker.mjs +234 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-factory.mjs +278 -0
- package/all/copy-overwrite/scripts/lib/npm-update-controller-recipe.mjs +135 -0
- package/all/copy-overwrite/scripts/lib/npm-update-execution-adapter.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-hooks.mjs +214 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-install.mjs +267 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate-proof.mjs +99 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gate.mjs +300 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-dispatch.mjs +182 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-grants.mjs +156 -0
- package/all/copy-overwrite/scripts/lib/npm-update-gh-requests.mjs +221 -0
- package/all/copy-overwrite/scripts/lib/npm-update-github.mjs +214 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper-graph.mjs +238 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper-inventory.mjs +126 -0
- package/all/copy-overwrite/scripts/lib/npm-update-helper.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-installation.mjs +116 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-preload.mjs +153 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-provider.mjs +207 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hook-read-client.mjs +164 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hosted-gate.mjs +272 -0
- package/all/copy-overwrite/scripts/lib/npm-update-hosted-hook.mjs +157 -0
- package/all/copy-overwrite/scripts/lib/npm-update-invariants.mjs +28 -0
- package/all/copy-overwrite/scripts/lib/npm-update-isolation.mjs +11 -0
- package/all/copy-overwrite/scripts/lib/npm-update-leaf-contract.mjs +171 -0
- package/all/copy-overwrite/scripts/lib/npm-update-leaf.mjs +194 -0
- package/all/copy-overwrite/scripts/lib/npm-update-native-process.mjs +155 -0
- package/all/copy-overwrite/scripts/lib/npm-update-npm.mjs +190 -0
- package/all/copy-overwrite/scripts/lib/npm-update-object.mjs +112 -0
- package/all/copy-overwrite/scripts/lib/npm-update-orchestrator.mjs +273 -0
- package/all/copy-overwrite/scripts/lib/npm-update-owner.mjs +292 -0
- package/all/copy-overwrite/scripts/lib/npm-update-prepare.mjs +263 -0
- package/all/copy-overwrite/scripts/lib/npm-update-process-core.mjs +179 -0
- package/all/copy-overwrite/scripts/lib/npm-update-process.mjs +16 -0
- package/all/copy-overwrite/scripts/lib/npm-update-publication.mjs +258 -0
- package/all/copy-overwrite/scripts/lib/npm-update-publish.mjs +258 -0
- package/all/copy-overwrite/scripts/lib/npm-update-quality.mjs +153 -0
- package/all/copy-overwrite/scripts/lib/npm-update-recovery.mjs +264 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-archive.mjs +204 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-graph.mjs +185 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime-transport.mjs +221 -0
- package/all/copy-overwrite/scripts/lib/npm-update-runtime.mjs +284 -0
- package/all/copy-overwrite/scripts/lib/npm-update-tool-launcher.mjs +287 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-environment.mjs +161 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-inspection.mjs +142 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-lifecycle.mjs +256 -0
- package/all/copy-overwrite/scripts/lib/npm-update-worker-policy.mjs +266 -0
- package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +230 -36
- package/all/copy-overwrite/scripts/lisa-automation-provenance.mjs +161 -0
- package/all/copy-overwrite/scripts/lisa-history-secrets.mjs +8 -1
- package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +89 -5
- package/all/copy-overwrite/scripts/lisa-npm-updater.mjs +204 -0
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +48 -123
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +107 -41
- package/all/copy-overwrite/scripts/npm-updater-gate-runtime.json +1 -0
- package/all/copy-overwrite/scripts/npm-updater-gate-supervisor.c +121 -0
- package/all/copy-overwrite/scripts/npm-updater-gate.Dockerfile +49 -0
- package/all/copy-overwrite/scripts/npm-updater-helper-graph.json +1085 -0
- package/dist/codex/scripts/block-no-verify.sh +89 -5
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +620 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +165 -13
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/block-no-verify.sh +89 -5
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/block-no-verify.agy.sh +89 -5
- package/plugins/lisa/hooks/block-no-verify.sh +89 -5
- package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +89 -5
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +89 -5
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +89 -5
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/block-no-verify.agy.sh +89 -5
- package/plugins/src/base/hooks/block-no-verify.sh +89 -5
- package/scripts/check-shipped-surface-removals.mjs +96 -24
- package/scripts/generate-npm-updater-helper-graph.mjs +184 -0
- package/scripts/two-channel-couplings.json +31 -7
- package/typescript/copy-contents/.husky/commit-msg +18 -0
- package/typescript/copy-overwrite/.prettierignore +2 -0
|
@@ -1016,7 +1016,7 @@ export function deployBranchEnvironments(config) {
|
|
|
1016
1016
|
return new Map([[branch, PRODUCTION]]);
|
|
1017
1017
|
}
|
|
1018
1018
|
|
|
1019
|
-
function trackerContract(config = readConfig()) {
|
|
1019
|
+
export function trackerContract(config = readConfig()) {
|
|
1020
1020
|
const provider = requireString(config.tracker, "tracker").toLowerCase();
|
|
1021
1021
|
const identityRepo = currentRepoIdentity(config);
|
|
1022
1022
|
if (provider === "github") {
|
|
@@ -1483,6 +1483,38 @@ export function soleWorkItem(text, contract, subject) {
|
|
|
1483
1483
|
return refs[0];
|
|
1484
1484
|
}
|
|
1485
1485
|
|
|
1486
|
+
/**
|
|
1487
|
+
* Resolve a required binding through the authoritative tracker contract.
|
|
1488
|
+
* Consumers supplying trusted committed configuration avoid reparsing trailers
|
|
1489
|
+
* or treating raw `current` output as a checked branch/queue identity.
|
|
1490
|
+
* This does not change ordinary offline/live validation semantics.
|
|
1491
|
+
* @param {string} message Complete final commit message.
|
|
1492
|
+
* @param {object} [options] Trusted configuration and strict live requirement.
|
|
1493
|
+
* @returns {object} Canonical identity and optional actual provider evidence.
|
|
1494
|
+
*/
|
|
1495
|
+
export function resolveWorkItemContext(message, options = {}) {
|
|
1496
|
+
const contract = trackerContract(options.config ?? readConfig());
|
|
1497
|
+
const state = readState(false);
|
|
1498
|
+
const ref = soleWorkItem(message, contract, COMMIT_SUBJECT);
|
|
1499
|
+
assertStateBranch(state);
|
|
1500
|
+
assertStateMatches(ref, contract);
|
|
1501
|
+
if (options.requireLive && contract.provider !== "github") {
|
|
1502
|
+
throw new TrackingError("Automation provenance requires GitHub tracking");
|
|
1503
|
+
}
|
|
1504
|
+
const issue = options.requireLive
|
|
1505
|
+
? githubIssue(ref, contract, options.execute ?? run)
|
|
1506
|
+
: undefined;
|
|
1507
|
+
return {
|
|
1508
|
+
ref,
|
|
1509
|
+
provider: contract.provider,
|
|
1510
|
+
repository: contract.repository,
|
|
1511
|
+
identityRepo: contract.identityRepo,
|
|
1512
|
+
branch: state.branch,
|
|
1513
|
+
lifecycle: contract.lifecycle,
|
|
1514
|
+
issue,
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1486
1518
|
/**
|
|
1487
1519
|
* The one work item a COMMIT message names.
|
|
1488
1520
|
* @param {string} message Commit message.
|
|
@@ -1843,28 +1875,34 @@ function typeFromLabels(labels) {
|
|
|
1843
1875
|
* @param {string|number} number GitHub issue number.
|
|
1844
1876
|
* @returns {string[]} State of every sub-issue.
|
|
1845
1877
|
*/
|
|
1846
|
-
|
|
1878
|
+
/** Literal typed GraphQL fields are shared by the canonical reader and closed native transport. */
|
|
1879
|
+
export function githubHierarchyArgs(contract, number, after) {
|
|
1847
1880
|
const [owner, repo] = contract.repository.split("/");
|
|
1848
1881
|
const query =
|
|
1849
1882
|
"query($owner:String!,$repo:String!,$number:Int!,$after:String){repository(owner:$owner,name:$repo){issue(number:$number){subIssues(first:100,after:$after){nodes{state}pageInfo{hasNextPage endCursor}}}}}";
|
|
1883
|
+
const args = [
|
|
1884
|
+
"api",
|
|
1885
|
+
"graphql",
|
|
1886
|
+
"-f",
|
|
1887
|
+
`query=${query}`,
|
|
1888
|
+
"-F",
|
|
1889
|
+
`owner=${owner}`,
|
|
1890
|
+
"-F",
|
|
1891
|
+
`repo=${repo}`,
|
|
1892
|
+
"-F",
|
|
1893
|
+
`number=${number}`,
|
|
1894
|
+
];
|
|
1895
|
+
if (after) args.push("-F", `after=${after}`);
|
|
1896
|
+
return args;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
function githubHierarchy(ref, contract, number, execute = run) {
|
|
1850
1900
|
const states = [];
|
|
1851
1901
|
const cursor = { after: null };
|
|
1852
1902
|
|
|
1853
1903
|
do {
|
|
1854
|
-
const args =
|
|
1855
|
-
|
|
1856
|
-
"graphql",
|
|
1857
|
-
"-f",
|
|
1858
|
-
`query=${query}`,
|
|
1859
|
-
"-F",
|
|
1860
|
-
`owner=${owner}`,
|
|
1861
|
-
"-F",
|
|
1862
|
-
`repo=${repo}`,
|
|
1863
|
-
"-F",
|
|
1864
|
-
`number=${number}`,
|
|
1865
|
-
];
|
|
1866
|
-
if (cursor.after) args.push("-F", `after=${cursor.after}`);
|
|
1867
|
-
const result = run("gh", args, { allowFailure: true });
|
|
1904
|
+
const args = githubHierarchyArgs(contract, number, cursor.after);
|
|
1905
|
+
const result = execute("gh", args, { allowFailure: true });
|
|
1868
1906
|
if (result.status !== 0) throw githubFailure(result, ref);
|
|
1869
1907
|
|
|
1870
1908
|
const response = safeJson(result.stdout, `GitHub issue ${ref} hierarchy`);
|
|
@@ -1952,20 +1990,25 @@ export function resetGhVersionCheck() {
|
|
|
1952
1990
|
ghVersionChecked = false;
|
|
1953
1991
|
}
|
|
1954
1992
|
|
|
1955
|
-
|
|
1956
|
-
|
|
1993
|
+
/** The body is required by recovery; all ordinary canonical validation fields remain present. */
|
|
1994
|
+
export function githubIssueViewArgs(repository, number) {
|
|
1995
|
+
return [
|
|
1996
|
+
"issue",
|
|
1997
|
+
"view",
|
|
1998
|
+
number,
|
|
1999
|
+
"--repo",
|
|
2000
|
+
repository,
|
|
2001
|
+
"--json",
|
|
2002
|
+
"number,url,state,body,labels,comments,closedByPullRequestsReferences",
|
|
2003
|
+
];
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
function githubIssue(ref, contract, execute = run) {
|
|
2007
|
+
assertGhVersion(execute);
|
|
1957
2008
|
const number = ref.slice(ref.lastIndexOf("#") + 1);
|
|
1958
|
-
const result =
|
|
2009
|
+
const result = execute(
|
|
1959
2010
|
"gh",
|
|
1960
|
-
|
|
1961
|
-
"issue",
|
|
1962
|
-
"view",
|
|
1963
|
-
number,
|
|
1964
|
-
"--repo",
|
|
1965
|
-
contract.repository,
|
|
1966
|
-
"--json",
|
|
1967
|
-
"number,url,state,labels,comments,closedByPullRequestsReferences",
|
|
1968
|
-
],
|
|
2011
|
+
githubIssueViewArgs(contract.repository, number),
|
|
1969
2012
|
{
|
|
1970
2013
|
allowFailure: true,
|
|
1971
2014
|
}
|
|
@@ -1985,7 +2028,7 @@ function githubIssue(ref, contract) {
|
|
|
1985
2028
|
assertLeaf(
|
|
1986
2029
|
ref,
|
|
1987
2030
|
typeFromLabels(issue.labels),
|
|
1988
|
-
githubHierarchy(ref, contract, number)
|
|
2031
|
+
githubHierarchy(ref, contract, number, execute)
|
|
1989
2032
|
);
|
|
1990
2033
|
return issue;
|
|
1991
2034
|
}
|
|
@@ -2410,7 +2453,7 @@ export function textContainsBacklink(value, prUrl) {
|
|
|
2410
2453
|
* @param {string} prUrl Pull request URL.
|
|
2411
2454
|
* @returns {string} The comment body.
|
|
2412
2455
|
*/
|
|
2413
|
-
function backlinkBody(prUrl) {
|
|
2456
|
+
export function backlinkBody(prUrl) {
|
|
2414
2457
|
return `${MARKER} ${prUrl}`;
|
|
2415
2458
|
}
|
|
2416
2459
|
|
|
@@ -2502,7 +2545,7 @@ function managedBacklinkTarget(body) {
|
|
|
2502
2545
|
* @returns {{mine: unknown, others: number}} This PR's comment, and how many
|
|
2503
2546
|
* managed comments belong to OTHER pull requests.
|
|
2504
2547
|
*/
|
|
2505
|
-
function partitionBacklinks(comments, prUrl, bodyOf) {
|
|
2548
|
+
export function partitionBacklinks(comments, prUrl, bodyOf) {
|
|
2506
2549
|
const mine = [];
|
|
2507
2550
|
let others = 0;
|
|
2508
2551
|
for (const comment of comments) {
|
|
@@ -2538,6 +2581,33 @@ export function backlinkReport(outcome, ref, prUrl) {
|
|
|
2538
2581
|
);
|
|
2539
2582
|
}
|
|
2540
2583
|
|
|
2584
|
+
/** Complete canonical pagination is shared by the writer and its scoped controller. */
|
|
2585
|
+
export function githubBacklinkListArgs(repository, number) {
|
|
2586
|
+
if (
|
|
2587
|
+
!/^[\w.-]+\/[\w.-]+$/.test(repository) ||
|
|
2588
|
+
!/^[1-9]\d*$/.test(String(number))
|
|
2589
|
+
)
|
|
2590
|
+
throw new Error("invalid canonical GitHub backlink repository/issue");
|
|
2591
|
+
return [
|
|
2592
|
+
"api",
|
|
2593
|
+
"--paginate",
|
|
2594
|
+
"--slurp",
|
|
2595
|
+
`repos/${repository}/issues/${number}/comments?per_page=100`,
|
|
2596
|
+
];
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
/** Complete slurped pages remain bounded and are shared by the canonical writer and controller grant. */
|
|
2600
|
+
export function githubBacklinkComments(pages) {
|
|
2601
|
+
if (
|
|
2602
|
+
!Array.isArray(pages) ||
|
|
2603
|
+
pages.length < 1 ||
|
|
2604
|
+
pages.length > 100 ||
|
|
2605
|
+
pages.some(page => !Array.isArray(page) || page.length > 100)
|
|
2606
|
+
)
|
|
2607
|
+
throw new Error("invalid or over-bound GitHub backlink pages");
|
|
2608
|
+
return pages.flat();
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2541
2611
|
/**
|
|
2542
2612
|
* Establish the backlink on a GitHub issue.
|
|
2543
2613
|
* @param {string} ref Canonical `owner/repo#number` reference.
|
|
@@ -2547,17 +2617,13 @@ export function backlinkReport(outcome, ref, prUrl) {
|
|
|
2547
2617
|
*/
|
|
2548
2618
|
function githubBacklink(ref, prUrl) {
|
|
2549
2619
|
const [repository, number] = ref.split("#");
|
|
2550
|
-
const listing = run(
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
"api",
|
|
2554
|
-
"--paginate",
|
|
2555
|
-
`repos/${repository}/issues/${number}/comments?per_page=100`,
|
|
2556
|
-
],
|
|
2557
|
-
{ allowFailure: true }
|
|
2558
|
-
);
|
|
2620
|
+
const listing = run("gh", githubBacklinkListArgs(repository, number), {
|
|
2621
|
+
allowFailure: true,
|
|
2622
|
+
});
|
|
2559
2623
|
if (listing.status !== 0) throw githubFailure(listing, ref);
|
|
2560
|
-
const comments =
|
|
2624
|
+
const comments = githubBacklinkComments(
|
|
2625
|
+
safeJson(listing.stdout, `GitHub comments on ${ref}`)
|
|
2626
|
+
);
|
|
2561
2627
|
// This listing is the read-before-write, and it is fetched here rather than
|
|
2562
2628
|
// passed in for exactly that reason: the version you last wrote is not the
|
|
2563
2629
|
// version that is live on a surface other agents also comment on.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"platforms":[],"recipeSha256":"260d194175737ed1cfdf6d208696bb58d035a45b2fd27c83a54e75be65ab5cb0","seccomp":{"profile":{"archMap":[{"architecture":"SCMP_ARCH_X86_64","subArchitectures":["SCMP_ARCH_X86","SCMP_ARCH_X32"]},{"architecture":"SCMP_ARCH_AARCH64","subArchitectures":["SCMP_ARCH_ARM"]},{"architecture":"SCMP_ARCH_MIPS64","subArchitectures":["SCMP_ARCH_MIPS","SCMP_ARCH_MIPS64N32"]},{"architecture":"SCMP_ARCH_MIPS64N32","subArchitectures":["SCMP_ARCH_MIPS","SCMP_ARCH_MIPS64"]},{"architecture":"SCMP_ARCH_MIPSEL64","subArchitectures":["SCMP_ARCH_MIPSEL","SCMP_ARCH_MIPSEL64N32"]},{"architecture":"SCMP_ARCH_MIPSEL64N32","subArchitectures":["SCMP_ARCH_MIPSEL","SCMP_ARCH_MIPSEL64"]},{"architecture":"SCMP_ARCH_S390X","subArchitectures":["SCMP_ARCH_S390"]},{"architecture":"SCMP_ARCH_RISCV64","subArchitectures":null},{"architecture":"SCMP_ARCH_LOONGARCH64","subArchitectures":null}],"defaultAction":"SCMP_ACT_ERRNO","defaultErrnoRet":1,"syscalls":[{"action":"SCMP_ACT_ALLOW","names":["accept","accept4","access","adjtimex","alarm","bind","brk","cachestat","capget","capset","chdir","chmod","chown","chown32","clock_adjtime","clock_adjtime64","clock_getres","clock_getres_time64","clock_gettime","clock_gettime64","clock_nanosleep","clock_nanosleep_time64","close","close_range","connect","copy_file_range","creat","dup","dup2","dup3","epoll_create","epoll_create1","epoll_ctl","epoll_ctl_old","epoll_pwait","epoll_pwait2","epoll_wait","epoll_wait_old","eventfd","eventfd2","execve","execveat","exit","exit_group","faccessat","faccessat2","fadvise64","fadvise64_64","fallocate","fanotify_mark","fchdir","fchmod","fchmodat","fchmodat2","fchown","fchown32","fchownat","fcntl","fcntl64","fdatasync","fgetxattr","flistxattr","flock","fork","fremovexattr","fsetxattr","fstat","fstat64","fstatat64","fstatfs","fstatfs64","fsync","ftruncate","ftruncate64","futex","futex_requeue","futex_time64","futex_wait","futex_waitv","futex_wake","futimesat","getcpu","getcwd","getdents","getdents64","getegid","getegid32","geteuid","geteuid32","getgid","getgid32","getgroups","getgroups32","getitimer","getpeername","getpgid","getpgrp","getpid","getppid","getpriority","getrandom","getresgid","getresgid32","getresuid","getresuid32","getrlimit","get_robust_list","getrusage","getsid","getsockname","getsockopt","get_thread_area","gettid","gettimeofday","getuid","getuid32","getxattr","getxattrat","inotify_add_watch","inotify_init","inotify_init1","inotify_rm_watch","io_cancel","ioctl","io_destroy","io_getevents","io_pgetevents","io_pgetevents_time64","ioprio_get","ioprio_set","io_setup","io_submit","ipc","kill","landlock_add_rule","landlock_create_ruleset","landlock_restrict_self","lchown","lchown32","lgetxattr","link","linkat","listen","listmount","listxattr","listxattrat","llistxattr","_llseek","lremovexattr","lseek","lsetxattr","lstat","lstat64","madvise","map_shadow_stack","membarrier","memfd_create","memfd_secret","mincore","mkdir","mkdirat","mknod","mknodat","mlock","mlock2","mlockall","mmap","mmap2","mprotect","mq_getsetattr","mq_notify","mq_open","mq_timedreceive","mq_timedreceive_time64","mq_timedsend","mq_timedsend_time64","mq_unlink","mremap","mseal","msgctl","msgget","msgrcv","msgsnd","msync","munlock","munlockall","munmap","name_to_handle_at","nanosleep","newfstatat","_newselect","open","openat","openat2","pause","pidfd_open","pidfd_send_signal","pipe","pipe2","pkey_alloc","pkey_free","pkey_mprotect","poll","ppoll","ppoll_time64","prctl","pread64","preadv","preadv2","prlimit64","process_mrelease","pselect6","pselect6_time64","pwrite64","pwritev","pwritev2","read","readahead","readlink","readlinkat","readv","recv","recvfrom","recvmmsg","recvmmsg_time64","recvmsg","remap_file_pages","removexattr","removexattrat","rename","renameat","renameat2","restart_syscall","riscv_hwprobe","rmdir","rseq","rt_sigaction","rt_sigpending","rt_sigprocmask","rt_sigqueueinfo","rt_sigreturn","rt_sigsuspend","rt_sigtimedwait","rt_sigtimedwait_time64","rt_tgsigqueueinfo","sched_getaffinity","sched_getattr","sched_getparam","sched_get_priority_max","sched_get_priority_min","sched_getscheduler","sched_rr_get_interval","sched_rr_get_interval_time64","sched_setaffinity","sched_setattr","sched_setparam","sched_setscheduler","sched_yield","seccomp","select","semctl","semget","semop","semtimedop","semtimedop_time64","send","sendfile","sendfile64","sendmmsg","sendmsg","sendto","setfsgid","setfsgid32","setfsuid","setfsuid32","setgid","setgid32","setgroups","setgroups32","setitimer","setpgid","setpriority","setregid","setregid32","setresgid","setresgid32","setresuid","setresuid32","setreuid","setreuid32","setrlimit","set_robust_list","setsid","setsockopt","set_thread_area","set_tid_address","setuid","setuid32","setxattr","setxattrat","shmat","shmctl","shmdt","shmget","shutdown","sigaltstack","signalfd","signalfd4","sigprocmask","sigreturn","socketcall","socketpair","splice","stat","stat64","statfs","statfs64","statmount","statx","symlink","symlinkat","sync","sync_file_range","syncfs","sysinfo","tee","tgkill","time","timer_create","timer_delete","timer_getoverrun","timer_gettime","timer_gettime64","timer_settime","timer_settime64","timerfd_create","timerfd_gettime","timerfd_gettime64","timerfd_settime","timerfd_settime64","times","tkill","truncate","truncate64","ugetrlimit","umask","uname","unlink","unlinkat","uretprobe","utime","utimensat","utimensat_time64","utimes","vfork","vmsplice","wait4","waitid","waitpid","write","writev"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_LT","value":3}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":7}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":8}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":9}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":10}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":13}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":14}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":15}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":16}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":17}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":18}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":21}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":22}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":24}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":26}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":27}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":28}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":29}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":30}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":31}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":32}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":33}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":35}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":36}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":39}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":41}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":42}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":43}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":44}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":45}],"names":["socket"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":0}],"names":["personality"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":8}],"names":["personality"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":131072}],"names":["personality"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":131080}],"names":["personality"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_EQ","value":4294967295}],"names":["personality"]},{"action":"SCMP_ACT_ALLOW","includes":{"arches":["ppc64le"]},"names":["sync_file_range2","swapcontext"]},{"action":"SCMP_ACT_ALLOW","includes":{"arches":["arm","arm64"]},"names":["arm_fadvise64_64","arm_sync_file_range","sync_file_range2","breakpoint","cacheflush","set_tls"]},{"action":"SCMP_ACT_ALLOW","includes":{"arches":["amd64","x32"]},"names":["arch_prctl"]},{"action":"SCMP_ACT_ALLOW","includes":{"arches":["amd64","x32","x86"]},"names":["modify_ldt"]},{"action":"SCMP_ACT_ALLOW","includes":{"arches":["s390","s390x"]},"names":["s390_pci_mmio_read","s390_pci_mmio_write","s390_runtime_instr"]},{"action":"SCMP_ACT_ALLOW","includes":{"arches":["riscv64"]},"names":["riscv_flush_icache"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_ADMIN"]},"names":["clone","clone3","fanotify_init","fsconfig","fsmount","fsopen","fspick","lookup_dcookie","lsm_get_self_attr","lsm_list_modules","lsm_set_self_attr","mount_setattr","move_mount","open_tree","perf_event_open","quotactl","quotactl_fd","setdomainname","sethostname","syslog","umount"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":0,"op":"SCMP_CMP_MASKED_EQ","value":2114060288}],"excludes":{"arches":["s390","s390x"],"caps":["CAP_SYS_ADMIN"]},"names":["clone"]},{"action":"SCMP_ACT_ALLOW","args":[{"index":1,"op":"SCMP_CMP_MASKED_EQ","value":2114060288}],"comment":"s390 parameter ordering for clone is different","excludes":{"caps":["CAP_SYS_ADMIN"]},"includes":{"arches":["s390","s390x"]},"names":["clone"]},{"action":"SCMP_ACT_ERRNO","errnoRet":38,"excludes":{"caps":["CAP_SYS_ADMIN"]},"names":["clone3"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_BOOT"]},"names":["reboot"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_CHROOT"]},"names":["chroot"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_MODULE"]},"names":["delete_module","init_module","finit_module"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_PACCT"]},"names":["acct"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_PTRACE"]},"names":["kcmp","pidfd_getfd","process_madvise"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_RAWIO"]},"names":["iopl","ioperm"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_TIME"]},"names":["settimeofday","stime","clock_settime","clock_settime64"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_TTY_CONFIG"]},"names":["vhangup"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYS_NICE"]},"names":["get_mempolicy","mbind","set_mempolicy","set_mempolicy_home_node"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_SYSLOG"]},"names":["syslog"]},{"action":"SCMP_ACT_ALLOW","includes":{"caps":["CAP_PERFMON"]},"names":["perf_event_open"]}]},"sha256":"5c3af609ff2ca4186b0c0d8eef81c75980d0ca67224ec4a0052ea44e710331e2"},"services":[],"supervisorSha256":"2506d8750694b93169f70e71d4c9dd68de0a0724bf9622bf9e15fa6cd2404b69","version":1}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/* This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
2
|
+
* Do not edit directly — durable changes belong upstream in Lisa. */
|
|
3
|
+
/* The fixed nonroot PID1 retains deadline/verdict authority across child exec. */
|
|
4
|
+
#define _POSIX_C_SOURCE 200809L
|
|
5
|
+
#include <errno.h>
|
|
6
|
+
#include <signal.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#include <sys/prctl.h>
|
|
11
|
+
#include <sys/types.h>
|
|
12
|
+
#include <sys/wait.h>
|
|
13
|
+
#include <time.h>
|
|
14
|
+
#include <unistd.h>
|
|
15
|
+
|
|
16
|
+
static volatile sig_atomic_t interrupted = 0;
|
|
17
|
+
|
|
18
|
+
static void interruption(int signal_number) {
|
|
19
|
+
interrupted = signal_number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static long long milliseconds(void) {
|
|
23
|
+
struct timespec now;
|
|
24
|
+
if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) return -1;
|
|
25
|
+
return (long long)now.tv_sec * 1000 + now.tv_nsec / 1000000;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static void pause_briefly(void) {
|
|
29
|
+
const struct timespec delay = {0, 20000000};
|
|
30
|
+
(void)nanosleep(&delay, NULL);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static int deadline_argument(const char *value) {
|
|
34
|
+
if (!value || !*value) return -1;
|
|
35
|
+
for (const char *p = value; *p; ++p) {
|
|
36
|
+
if (*p < '0' || *p > '9') return -1;
|
|
37
|
+
}
|
|
38
|
+
errno = 0;
|
|
39
|
+
char *end = NULL;
|
|
40
|
+
long result = strtol(value, &end, 10);
|
|
41
|
+
if (errno || !end || *end || result < 1 || result > 1800000) return -1;
|
|
42
|
+
return (int)result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Namespace-wide signals are used only after main has established actual PID1. */
|
|
46
|
+
static int cleanup_children(void) {
|
|
47
|
+
long long started = milliseconds();
|
|
48
|
+
if (started < 0 || (kill(-1, SIGTERM) != 0 && errno != ESRCH)) return -1;
|
|
49
|
+
int killed = 0;
|
|
50
|
+
for (;;) {
|
|
51
|
+
int status;
|
|
52
|
+
pid_t reaped;
|
|
53
|
+
do { reaped = waitpid(-1, &status, WNOHANG); } while (reaped > 0);
|
|
54
|
+
if (reaped < 0 && errno == ECHILD) return 0;
|
|
55
|
+
if (reaped < 0 && errno != EINTR) return -1;
|
|
56
|
+
long long now = milliseconds();
|
|
57
|
+
if (now < 0 || now - started >= 4000) return -1;
|
|
58
|
+
if (!killed && now - started >= 2000) {
|
|
59
|
+
if (kill(-1, SIGKILL) != 0 && errno != ESRCH) return -1;
|
|
60
|
+
killed = 1;
|
|
61
|
+
}
|
|
62
|
+
pause_briefly();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Only a real waitpid result can be the original command's successful verdict. */
|
|
67
|
+
static int await_command(pid_t child, int duration) {
|
|
68
|
+
long long started = milliseconds();
|
|
69
|
+
if (started < 0) return 125;
|
|
70
|
+
for (;;) {
|
|
71
|
+
int status = 0;
|
|
72
|
+
pid_t result = waitpid(child, &status, WNOHANG);
|
|
73
|
+
if (interrupted) return 128 + interrupted;
|
|
74
|
+
if (result == child) {
|
|
75
|
+
if (WIFEXITED(status)) return WEXITSTATUS(status);
|
|
76
|
+
if (WIFSIGNALED(status)) return 128 + WTERMSIG(status);
|
|
77
|
+
return 125;
|
|
78
|
+
}
|
|
79
|
+
if (result < 0 && errno != EINTR) return 125;
|
|
80
|
+
long long now = milliseconds();
|
|
81
|
+
if (now < 0) return 125;
|
|
82
|
+
if (now - started >= duration) return 124;
|
|
83
|
+
pause_briefly();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
int main(int argc, char **argv) {
|
|
88
|
+
if (argc == 2 && strcmp(argv[1], "--version") == 0) {
|
|
89
|
+
puts("lisa-npm-supervisor 1");
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
int duration = argc >= 4 ? deadline_argument(argv[1]) : -1;
|
|
93
|
+
if (duration < 0 || strcmp(argv[2], "--") != 0 || argv[3][0] != '/' ||
|
|
94
|
+
getpid() != 1 || getuid() == 0 || getgid() == 0) {
|
|
95
|
+
fputs("lisa supervisor: invalid nonroot PID1 invocation\n", stderr);
|
|
96
|
+
return 125;
|
|
97
|
+
}
|
|
98
|
+
if (prctl(PR_SET_DUMPABLE, 0) != 0 || prctl(PR_GET_DUMPABLE) != 0) {
|
|
99
|
+
fputs("lisa supervisor: dumpability protection unavailable\n", stderr);
|
|
100
|
+
return 125;
|
|
101
|
+
}
|
|
102
|
+
struct sigaction action;
|
|
103
|
+
memset(&action, 0, sizeof action);
|
|
104
|
+
action.sa_handler = interruption;
|
|
105
|
+
if (sigemptyset(&action.sa_mask) != 0 || sigaction(SIGTERM, &action, NULL) != 0 ||
|
|
106
|
+
sigaction(SIGINT, &action, NULL) != 0 || sigaction(SIGHUP, &action, NULL) != 0) return 125;
|
|
107
|
+
fprintf(stderr, "lisa supervisor: pid=1 uid=%lu gid=%lu dumpable=0\n",
|
|
108
|
+
(unsigned long)getuid(), (unsigned long)getgid());
|
|
109
|
+
if (fflush(stderr) != 0) return 125;
|
|
110
|
+
pid_t child = fork();
|
|
111
|
+
if (child < 0) return 125;
|
|
112
|
+
if (child == 0) {
|
|
113
|
+
if (setpgid(0, 0) != 0) _exit(125);
|
|
114
|
+
execv(argv[3], argv + 3);
|
|
115
|
+
_exit(errno == ENOENT ? 127 : 126);
|
|
116
|
+
}
|
|
117
|
+
int result = await_command(child, duration);
|
|
118
|
+
if (cleanup_children() != 0) return 125;
|
|
119
|
+
if (interrupted) return 128 + interrupted;
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
2
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
3
|
+
# Trusted fixed recipe only. Application/package files never enter this build context.
|
|
4
|
+
ARG TARGETARCH
|
|
5
|
+
FROM --platform=linux/amd64 node@sha256:25330af3531fb5e23318554a0aa911125b6e91b1b777edf7655501d207c067a2 AS node-amd64
|
|
6
|
+
FROM --platform=linux/arm64 node@sha256:a0ddbc73510e98f5e824fd64266ffe1c2c343ba9cf260d95ca2985ad632a3f3e AS node-arm64
|
|
7
|
+
FROM node-${TARGETARCH} AS node-runtime
|
|
8
|
+
FROM --platform=linux/amd64 ruby@sha256:bcb412ff5c2bdace9af8171c410745e227aea813fa951caab539b2f18623d239 AS ruby-amd64
|
|
9
|
+
FROM --platform=linux/arm64 ruby@sha256:2836fb28bf6f9f1d88015861df0b52424daeb499f2816ed9e4ef31c3bc181909 AS ruby-arm64
|
|
10
|
+
FROM ruby-${TARGETARCH}
|
|
11
|
+
ARG TARGETARCH
|
|
12
|
+
COPY --from=node-runtime /usr/local/bin/node /opt/node/bin/node
|
|
13
|
+
COPY --from=node-runtime /usr/local/lib/node_modules /opt/node/lib/node_modules
|
|
14
|
+
ENV PATH=/opt/node/bin:/usr/local/bin:/usr/bin:/bin
|
|
15
|
+
RUN apt-get update && apt-get install --yes --no-install-recommends \
|
|
16
|
+
bash ca-certificates curl git unzip passwd build-essential pkg-config libmariadb-dev libmariadb-dev-compat libyaml-dev libvips42 libxml2-dev libxslt1-dev \
|
|
17
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
18
|
+
COPY npm-updater-gate-supervisor.c /tmp/npm-updater-gate-supervisor.c
|
|
19
|
+
RUN cc -std=c11 -Wall -Wextra -Werror -O2 /tmp/npm-updater-gate-supervisor.c \
|
|
20
|
+
-o /usr/local/bin/lisa-npm-supervisor && rm /tmp/npm-updater-gate-supervisor.c
|
|
21
|
+
RUN set -eu; \
|
|
22
|
+
curl --fail --location --silent --show-error https://registry.npmjs.org/npm/-/npm-11.21.0.tgz --output /tmp/npm.tgz; \
|
|
23
|
+
test "$(openssl dgst -sha512 -binary /tmp/npm.tgz | base64 -w0)" = 'Zov8KhamNneiLdELtj5YALtNmJW4L4fCLTzjfpzXG2w6MSHcf0UxgdlK5uloCuksWT+7mGUU7wi79cO6RqivPg=='; \
|
|
24
|
+
mkdir /opt/npm; tar -xzf /tmp/npm.tgz --strip-components=1 -C /opt/npm; \
|
|
25
|
+
ln -s /opt/npm/bin/npm-cli.js /opt/node/bin/npm; \
|
|
26
|
+
curl --fail --location --silent --show-error https://rubygems.org/downloads/bundler-2.4.10.gem --output /tmp/bundler.gem; \
|
|
27
|
+
echo 'b9806fa944063a6a8676a8f9ed4c7c776a36c3bc82f26c5760867a0285b4a121 /tmp/bundler.gem' | sha256sum --check --strict; \
|
|
28
|
+
gem install --local /tmp/bundler.gem --no-document; \
|
|
29
|
+
rm /tmp/npm.tgz /tmp/bundler.gem
|
|
30
|
+
RUN set -eu; \
|
|
31
|
+
case "$TARGETARCH" in \
|
|
32
|
+
amd64) bun_arch=x64; bun_sha=0322b17f0722da76a64298aad498225aedcbf6df1008a1dee45e16ecb226a3f1; gh_arch=amd64; gh_sha=83d5c2ccad5498f58bf6368acb1ab32588cf43ab3a4b1c301bf36328b1c8bd60; leaks_arch=x64; leaks_sha=551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb ;; \
|
|
33
|
+
arm64) bun_arch=aarch64; bun_sha=4e9deb6814a7ec7f68725ddd97d0d7b4065bcda9a850f69d497567e995a7fa33; gh_arch=arm64; gh_sha=06f86ec7103d41993b76cd78072f43595c34aaa56506d971d9860e67140bf909; leaks_arch=arm64; leaks_sha=e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080 ;; \
|
|
34
|
+
*) echo 'Unsupported qualified architecture' >&2; exit 1 ;; \
|
|
35
|
+
esac; \
|
|
36
|
+
curl --fail --location --silent --show-error "https://github.com/oven-sh/bun/releases/download/bun-v1.3.8/bun-linux-${bun_arch}.zip" --output /tmp/bun.zip; \
|
|
37
|
+
echo "${bun_sha} /tmp/bun.zip" | sha256sum --check --strict; \
|
|
38
|
+
unzip -p /tmp/bun.zip "bun-linux-${bun_arch}/bun" > /usr/local/bin/bun; chmod 755 /usr/local/bin/bun; \
|
|
39
|
+
curl --fail --location --silent --show-error "https://github.com/cli/cli/releases/download/v2.96.0/gh_2.96.0_linux_${gh_arch}.tar.gz" --output /tmp/gh.tgz; \
|
|
40
|
+
echo "${gh_sha} /tmp/gh.tgz" | sha256sum --check --strict; \
|
|
41
|
+
tar -xzOf /tmp/gh.tgz "gh_2.96.0_linux_${gh_arch}/bin/gh" > /usr/local/bin/gh; chmod 755 /usr/local/bin/gh; \
|
|
42
|
+
curl --fail --location --silent --show-error "https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_${leaks_arch}.tar.gz" --output /tmp/gitleaks.tgz; \
|
|
43
|
+
echo "${leaks_sha} /tmp/gitleaks.tgz" | sha256sum --check --strict; \
|
|
44
|
+
tar -xzOf /tmp/gitleaks.tgz gitleaks > /usr/local/bin/gitleaks; chmod 755 /usr/local/bin/gitleaks; \
|
|
45
|
+
rm /tmp/bun.zip /tmp/gh.tgz /tmp/gitleaks.tgz; \
|
|
46
|
+
node --version; node /opt/npm/bin/npm-cli.js --version; ruby --version; bundle _2.4.10_ --version; \
|
|
47
|
+
/usr/sbin/useradd --uid 2001 --user-group --create-home candidate
|
|
48
|
+
USER 2001:2001
|
|
49
|
+
WORKDIR /workspace
|