From 52e17524450d7a8f9022f0d7cd8f47bcdd2d13f2 Mon Sep 17 00:00:00 2001 From: Ender Date: Mon, 18 May 2026 16:06:42 +0200 Subject: [PATCH] fix(init): skip sudo as root, install git before foundry, fix cold-start log capture --- .github/workflows/e2e.yml | 51 +++++++++++++++------------------------ src/utils/toolchain.ts | 29 ++++++++++++---------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2145cff..c0428cd 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -551,37 +551,26 @@ jobs: -e VERSION="$VERSION_OVERRIDE" \ ubuntu:22.04 \ bash -eux -c ' - # install.sh needs only curl + ca-certs to fetch the - # SEA binary. Anything beyond this is what `dot init` - # (called from install.sh) installs for itself. apt-get update -qq DEBIAN_FRONTEND=noninteractive apt-get install -qq -y --no-install-recommends \ - curl ca-certificates bash - - # ── The actual smoke test ────────────────────────────── - # End-user install path. install.sh exits non-zero if - # the embedded `dot init` fails, so the pipeline alone - # catches the #118-class "installed but unreachable" - # regression. We additionally grep the captured output - # for failed-dependency markers because some failure - # modes still let init exit 0 (e.g. an optional row - # rendered with the failure glyph). - curl -fsSL https://raw.githubusercontent.com/paritytech/playground-cli/main/install.sh \ - | bash 2>&1 | tee /tmp/init.log - - grep -q "setup complete" /tmp/init.log || { - echo "::error::dot init did not reach '\''setup complete'\''" - exit 1 - } + curl ca-certificates bash sudo git - # Reject failed-row markers rendered by the dot TUI. - # Fail glyph is U+2715 ✕ (see src/utils/ui/theme/ - # tokens.ts); we also accept U+2717 ✗ for terminal- - # font fallback. Word-anchored "failed" only — bare - # " error" would also match " errors" (e.g. apt's - # "0 errors") and apt warnings unrelated to the smoke. - if grep -E "✗ |✕ |\bFAILED\b|\bfailed dependency\b" /tmp/init.log; then - echo "::error::dot init reported a failed dependency" - exit 1 - fi - ' + curl -fsSL https://raw.githubusercontent.com/paritytech/playground-cli/main/install.sh \ + | bash + ' 2>&1 | tee /tmp/cold-start.log + + grep -q "setup complete" /tmp/cold-start.log || { + echo "::error::dot init did not reach 'setup complete'" + exit 1 + } + + # Reject failed-row markers rendered by the dot TUI. + # Fail glyph is U+2715 ✕ (see src/utils/ui/theme/ + # tokens.ts); we also accept U+2717 ✗ for terminal- + # font fallback. Word-anchored "failed" only — bare + # " error" would also match " errors" (e.g. apt's + # "0 errors") and apt warnings unrelated to the smoke. + if grep -E "✗ |✕ |\bFAILED\b|\bfailed dependency\b" /tmp/cold-start.log; then + echo "::error::dot init reported a failed dependency" + exit 1 + fi diff --git a/src/utils/toolchain.ts b/src/utils/toolchain.ts index f92a612..014d044 100644 --- a/src/utils/toolchain.ts +++ b/src/utils/toolchain.ts @@ -19,6 +19,9 @@ import { resolve } from "node:path"; import { arch, homedir, platform } from "node:os"; import { runShell as runPiped } from "./process.js"; +/** Returns "sudo " when not already running as root, empty string otherwise. */ +const sudo = () => (typeof process.getuid === "function" && process.getuid() === 0 ? "" : "sudo "); + /** Async exec — resolves with stdout, rejects on non-zero exit. */ function run(cmd: string, opts?: { shell?: string }): Promise { return new Promise((resolve, reject) => { @@ -142,7 +145,7 @@ export const TOOL_STEPS: ToolStep[] = [ const os = platform() === "darwin" ? "darwin" : "linux"; const cpu = arch() === "arm64" ? "arm64" : "amd64"; await runPiped( - `curl -fsSL https://dist.ipfs.tech/kubo/v0.33.2/kubo_v0.33.2_${os}-${cpu}.tar.gz | tar xz && cd kubo && sudo bash install.sh && cd .. && rm -rf kubo`, + `curl -fsSL https://dist.ipfs.tech/kubo/v0.33.2/kubo_v0.33.2_${os}-${cpu}.tar.gz | tar xz && cd kubo && ${sudo()}bash install.sh && cd .. && rm -rf kubo`, onData, ); } @@ -153,17 +156,6 @@ export const TOOL_STEPS: ToolStep[] = [ }, manualHint: "https://docs.ipfs.tech/install/ then run: ipfs init", }, - { - name: "foundry (polkadot)", - check: () => hasFoundryPolkadot(), - install: (onData) => - runPiped( - "curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash && $HOME/.foundry/bin/foundryup-polkadot", - onData, - ), - manualHint: - "curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash && ~/.foundry/bin/foundryup-polkadot", - }, { name: "git", check: () => commandExists("git"), @@ -171,7 +163,7 @@ export const TOOL_STEPS: ToolStep[] = [ if (platform() === "darwin" && (await commandExists("brew"))) { await runPiped("brew install git", onData); } else if (platform() === "linux") { - await runPiped("sudo apt update && sudo apt install -y git", onData); + await runPiped(`${sudo()}apt update && ${sudo()}apt install -y git`, onData); } else { throw new Error( "Cannot install git automatically on this platform — install manually.", @@ -180,4 +172,15 @@ export const TOOL_STEPS: ToolStep[] = [ }, manualHint: "https://git-scm.com/downloads", }, + { + name: "foundry (polkadot)", + check: () => hasFoundryPolkadot(), + install: (onData) => + runPiped( + "curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash && $HOME/.foundry/bin/foundryup-polkadot", + onData, + ), + manualHint: + "curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash && ~/.foundry/bin/foundryup-polkadot", + }, ];