-
Notifications
You must be signed in to change notification settings - Fork 0
ci: fresh-install smoke regression guard for the SDK-drift install crash #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,100 @@ | ||||||||||||||||||||
| name: smoke-install | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Regression guard for the 2026-09-01 P0: `npm i @wave-av/cli` resolved a broken | ||||||||||||||||||||
| # `@wave-av/sdk` release (2.1.2) through the `^2.0.11` semver range and every invocation | ||||||||||||||||||||
| # died before argv parsing with a module-resolution error. That class of bug — a real, | ||||||||||||||||||||
| # already-published dependency drifting a fresh install into a broken combination — only | ||||||||||||||||||||
| # shows up when you install the ACTUAL published tarball against the ACTUAL registry, so | ||||||||||||||||||||
| # this workflow builds the package, packs it, and installs the tarball into a throwaway | ||||||||||||||||||||
| # project exactly the way a real user's `npm install` would. Unit tests and type-check | ||||||||||||||||||||
| # cannot catch this: they run against the local, already-linked node_modules tree. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| on: | ||||||||||||||||||||
| pull_request: | ||||||||||||||||||||
| push: | ||||||||||||||||||||
| branches: [main] | ||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||
|
|
||||||||||||||||||||
| permissions: | ||||||||||||||||||||
| contents: read | ||||||||||||||||||||
|
|
||||||||||||||||||||
| concurrency: | ||||||||||||||||||||
| group: ${{ github.workflow }}-${{ github.ref }} | ||||||||||||||||||||
| cancel-in-progress: true | ||||||||||||||||||||
|
|
||||||||||||||||||||
| jobs: | ||||||||||||||||||||
| smoke: | ||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||
| timeout-minutes: 10 | ||||||||||||||||||||
| strategy: | ||||||||||||||||||||
| fail-fast: false | ||||||||||||||||||||
| matrix: | ||||||||||||||||||||
| node: [20, 22] | ||||||||||||||||||||
| steps: | ||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||
| with: | ||||||||||||||||||||
| persist-credentials: false | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - uses: actions/setup-node@v4 | ||||||||||||||||||||
| with: | ||||||||||||||||||||
| node-version: ${{ matrix.node }} | ||||||||||||||||||||
| registry-url: https://registry.npmjs.org | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||
| run: npm ci | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - name: Build | ||||||||||||||||||||
| run: npm run build | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - name: Pack tarball | ||||||||||||||||||||
| run: npm pack --pack-destination "$RUNNER_TEMP" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - name: Fresh install from the packed tarball (real registry, real deps) | ||||||||||||||||||||
| run: | | ||||||||||||||||||||
| mkdir -p "$RUNNER_TEMP/smoke" | ||||||||||||||||||||
| cd "$RUNNER_TEMP/smoke" | ||||||||||||||||||||
| npm init -y >/dev/null | ||||||||||||||||||||
| tarball=$(ls "$RUNNER_TEMP"/wave-av-cli-*.tgz | head -n1) | ||||||||||||||||||||
| npm i "$tarball" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| - name: wave --version / --help (module-resolution smoke) | ||||||||||||||||||||
| run: | | ||||||||||||||||||||
| cd "$RUNNER_TEMP/smoke" | ||||||||||||||||||||
| npx --yes wave --version | ||||||||||||||||||||
| npx --yes wave --help >/dev/null | ||||||||||||||||||||
|
Comment on lines
+63
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/smoke-install.yml
printf '%s\n' '--- package manifests ---'
find . -maxdepth 2 -type f \( -name package.json -o -name package-lock.json \) -print
for f in $(find . -maxdepth 2 -type f -name package.json -print); do
printf '%s\n' "--- $f ---"
cat "$f"
doneRepository: wave-av/cli Length of output: 6328 🌐 Web query:
💡 Result: When you use the npm exec command or the npx binary to run a package, npm checks if the package is present in the local node_modules/.bin directory [1][2][3]. If the package is not found locally, npm will automatically fetch (install) it into a temporary location within the npm cache [1][2][4]. The --yes (or -y) flag is used to suppress the confirmation prompt that npm displays before installing a missing package [1][5][6]. This ensures that the command proceeds immediately with the download and execution without requiring manual intervention [1][4]. Key details: - Automatic Fetching: If the requested package is not present in your local project dependencies, npm performs an ephemeral installation to a cache folder, which is then added to the system PATH for the duration of the command's execution [1][2][5]. - Prompt Suppression: The --yes flag explicitly authorizes this automatic installation [1][6]. If you do not provide this flag (and you are in an interactive terminal), npm will pause to ask for your permission to install the package [1][2]. - Modern Behavior: The standalone npx package was deprecated in npm v7.0.0 [1][2]. Modern versions of npx are effectively a wrapper for the npm exec command, and they share this same behavior [1][6]. Citations:
Run the installed binary directly. If the local 🤖 Prompt for AI Agents |
||||||||||||||||||||
|
|
||||||||||||||||||||
| - name: wave status / wave doctor (live gateway reachability) | ||||||||||||||||||||
| working-directory: ${{ runner.temp }}/smoke | ||||||||||||||||||||
| env: | ||||||||||||||||||||
| WAVE_GATEWAY_API_KEY: ${{ secrets.WAVE_GATEWAY_API_KEY }} | ||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/sh
set -eu
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/smoke-install.yml | sed -n '1,115p'
printf '%s\n' '--- workflow references and secret usage ---'
rg -n -C 3 'on:|pull_request|push:|workflow_dispatch|WAVE_GATEWAY_API_KEY|WAVE_API_KEY|npx|npm (run|pack|i)|npm install|run_check|environment:' .github/workflows/smoke-install.ymlRepository: wave-av/cli Length of output: 7637 🤖 get_repo_knowledge executed:
Length of output: 9553 Sensitive Data Exposure (CWE-200): Exposure of Sensitive Information to an Unauthorized Actor Reachability: External · Exploitability: Moderate Do not expose the gateway key to pull-request code. The 🤖 Prompt for AI Agents |
||||||||||||||||||||
| run: | | ||||||||||||||||||||
| if [ -z "$WAVE_GATEWAY_API_KEY" ]; then | ||||||||||||||||||||
| echo "skipped: WAVE_GATEWAY_API_KEY absent (fork or unset)" | ||||||||||||||||||||
| exit 0 | ||||||||||||||||||||
| fi | ||||||||||||||||||||
| export WAVE_API_KEY="$WAVE_GATEWAY_API_KEY" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Pass criteria: the process ran and produced a normal CLI response - a clean | ||||||||||||||||||||
| # exit, or a real HTTP-level auth/scope response (401/402/403 SCOPE_INSUFFICIENT), | ||||||||||||||||||||
| # or the command's own "not authenticated" business-logic exit. Fail criteria: the | ||||||||||||||||||||
| # output looks like the install-time crash class this workflow exists to catch - | ||||||||||||||||||||
| # a module-resolution / ESM-vs-CJS error that means the package never even started. | ||||||||||||||||||||
| run_check() { | ||||||||||||||||||||
| label="$1" | ||||||||||||||||||||
| shift | ||||||||||||||||||||
| set +e | ||||||||||||||||||||
| out=$("$@" 2>&1) | ||||||||||||||||||||
| code=$? | ||||||||||||||||||||
| set -e | ||||||||||||||||||||
| echo "$label exit=$code" | ||||||||||||||||||||
| echo "$out" | head -n 20 | ||||||||||||||||||||
| if echo "$out" | grep -qE 'is not defined in ES module scope|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_REQUIRE_ESM|ReferenceError|SyntaxError: Unexpected token|Cannot find package'; then | ||||||||||||||||||||
| echo "::error::$label failed with a module-resolution class error" | ||||||||||||||||||||
| return 1 | ||||||||||||||||||||
| fi | ||||||||||||||||||||
| echo "$label: process started and produced a normal CLI response - pass" | ||||||||||||||||||||
| return 0 | ||||||||||||||||||||
|
Comment on lines
+95
to
+96
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Fail unexpected nonzero command exits.
Proposed exit handling- echo "$label: process started and produced a normal CLI response - pass"
- return 0
+ if [ "$code" -eq 0 ] ||
+ echo "$out" | grep -qE '\b(401|402|403)\b|SCOPE_INSUFFICIENT|not authenticated'; then
+ echo "$label: normal CLI response - pass"
+ return 0
+ fi
+ echo "::error::$label exited unexpectedly ($code)"
+ return 1📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| run_check "wave doctor" npx --yes wave doctor | ||||||||||||||||||||
| run_check "wave status" npx --yes wave status | ||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: wave-av/cli
Length of output: 884
Security Misconfiguration (CWE-829): Inclusion of Functionality from Untrusted Control Sphere
Reachability: External · Exploitability: Difficult
Pin both actions to full commit SHAs.
actions/checkout@v4andactions/setup-node@v4use mutable references. Replace both tags with verified full commit SHAs and retain the release tags in comments for automated updates.🧰 Tools
🪛 zizmor (1.29.0)
[error] 34-34: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Source: Linters/SAST tools