strands-shell 0.2.0__tar.gz → 0.3.0__tar.gz
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.
- strands_shell-0.3.0/.github/CODEOWNERS +1 -0
- strands_shell-0.3.0/.github/scripts/group-release-notes.py +95 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/workflows/ci.yml +53 -8
- strands_shell-0.3.0/.github/workflows/release.yml +811 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/Cargo.lock +9 -9
- {strands_shell-0.2.0 → strands_shell-0.3.0}/Cargo.toml +1 -1
- {strands_shell-0.2.0 → strands_shell-0.3.0}/PKG-INFO +1 -1
- {strands_shell-0.2.0 → strands_shell-0.3.0}/package.json +3 -2
- {strands_shell-0.2.0 → strands_shell-0.3.0}/pyproject.toml +1 -1
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/vfs_kernel.rs +18 -11
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/shell_integration.rs +7 -1
- strands_shell-0.2.0/.github/workflows/release.yml +0 -458
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.cargo/config.toml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/actions/stamp-version/action.yml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/dependabot.yml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.github/workflows/pr-title.yml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/.gitignore +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/AGENTS.md +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/CODE_OF_CONDUCT.md +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/CONTRIBUTING.md +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/LICENSE +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/NOTICE +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/README.md +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/SECURITY.md +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/build.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/index.d.ts +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/index.js +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/python/strands_shell/__init__.py +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/scripts/build-wasm.sh +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/alias.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/cd.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/colon.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/echo.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/export.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/find.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/getopts.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/hash.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/local.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/lua.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/mod.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/printf.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/pwd.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/read.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/set.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/shift.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/test.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/trap.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/type_cmd.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/umask.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/unset.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/wait.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/builtins/xargs.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/cli.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/basename.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/cat.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/chmod.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/cp.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/curl.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/cut.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/date.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/dirname.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/echo.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/env.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/false.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/grep.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/head.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/jq.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/ln.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/ls.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/mkdir.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/mktemp.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/mod.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/mv.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/pwd.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/readlink.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/rm.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/rmdir.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/sed.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/sleep.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/sort.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/tail.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/tee.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/touch.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/tr.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/true.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/uniq.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/commands/wc.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/exec.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/io.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/js.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/lib.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/main.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/mcp.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/mcp_client.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/os.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/parser.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/prelude.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/python.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/shell.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/vfs.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/vfs_config.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/src/wasm_main.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/strands-shell-macros/Cargo.toml +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/strands-shell-macros/src/lib.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/config.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/curl_integration.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/js/test_bindings.mjs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/js/test_builder.mjs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/js/test_config.mjs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/lua_integration.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/mcp_integration.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/python/test_bindings.py +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/python/test_builder.py +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/python/test_config.py +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/ts/api.types.ts +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tests/vfs_unit.rs +0 -0
- {strands_shell-0.2.0 → strands_shell-0.3.0}/tsconfig.json +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @strands-agents/codeowners
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Group release-note commits by conventional-commit type.
|
|
3
|
+
|
|
4
|
+
Reads `<short-hash><TAB><subject>` lines on stdin (one commit each, as
|
|
5
|
+
produced by `git log --pretty=format:'%h%x09%s'`) and writes Markdown
|
|
6
|
+
release notes to stdout, bucketed by conventional-commit type (`feat`,
|
|
7
|
+
`fix`, `docs`, ...) instead of by author.
|
|
8
|
+
|
|
9
|
+
The header is drawn from the `NEW_TAG` / `PREV_TAG` environment variables
|
|
10
|
+
so the output matches the previous shortlog-based notes.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import re
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
# Conventional-commit types in the order they should appear, mapped to
|
|
18
|
+
# their section headings. Types not listed here fall through to "Other".
|
|
19
|
+
SECTIONS = [
|
|
20
|
+
("feat", "🚀 Features"),
|
|
21
|
+
("fix", "🐛 Fixes"),
|
|
22
|
+
("perf", "⚡ Performance"),
|
|
23
|
+
("refactor", "♻️ Refactoring"),
|
|
24
|
+
("docs", "📚 Documentation"),
|
|
25
|
+
("test", "✅ Tests"),
|
|
26
|
+
("build", "📦 Build"),
|
|
27
|
+
("ci", "👷 CI"),
|
|
28
|
+
("chore", "🔧 Chores"),
|
|
29
|
+
("revert", "⏪ Reverts"),
|
|
30
|
+
]
|
|
31
|
+
SECTION_TITLES = dict(SECTIONS)
|
|
32
|
+
OTHER_KEY = "other"
|
|
33
|
+
|
|
34
|
+
# `type(optional scope)!: subject` — captures the type and the remaining
|
|
35
|
+
# subject. The optional `!` and scope are conventional-commit syntax.
|
|
36
|
+
COMMIT_RE = re.compile(r"^(?P<type>[a-z]+)(?:\([^)]*\))?!?:\s*(?P<subject>.*)$")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def classify(subject):
|
|
40
|
+
"""Return the `section_key` for a commit subject line.
|
|
41
|
+
|
|
42
|
+
Only the type is parsed off, for bucketing; the subject itself is kept
|
|
43
|
+
verbatim (prefix included) by the caller so the rendered notes still
|
|
44
|
+
show the `feat:` / `fix:` convention.
|
|
45
|
+
"""
|
|
46
|
+
match = COMMIT_RE.match(subject)
|
|
47
|
+
if match and match.group("type") in SECTION_TITLES:
|
|
48
|
+
return match.group("type")
|
|
49
|
+
return OTHER_KEY
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def main():
|
|
53
|
+
buckets = {}
|
|
54
|
+
for line in sys.stdin:
|
|
55
|
+
line = line.rstrip("\n")
|
|
56
|
+
if not line:
|
|
57
|
+
continue
|
|
58
|
+
short_hash, _, subject = line.partition("\t")
|
|
59
|
+
key = classify(subject)
|
|
60
|
+
buckets.setdefault(key, []).append((short_hash, subject.strip()))
|
|
61
|
+
|
|
62
|
+
new_tag = os.environ.get("NEW_TAG", "")
|
|
63
|
+
prev_tag = os.environ.get("PREV_TAG", "")
|
|
64
|
+
|
|
65
|
+
out = []
|
|
66
|
+
out.append(f"## {new_tag}")
|
|
67
|
+
out.append("")
|
|
68
|
+
out.append(
|
|
69
|
+
f"_Auto-drafted from commits in `{prev_tag}..{new_tag}`, grouped by "
|
|
70
|
+
"conventional-commit type. Edit on the release page after publish if "
|
|
71
|
+
"you want a polished writeup; the canonical release notes live on the "
|
|
72
|
+
"website._"
|
|
73
|
+
)
|
|
74
|
+
out.append("")
|
|
75
|
+
|
|
76
|
+
# Known types first, in declared order; then the "Other" catch-all.
|
|
77
|
+
for key, title in SECTIONS + [(OTHER_KEY, "🔖 Other")]:
|
|
78
|
+
commits = buckets.get(key)
|
|
79
|
+
if not commits:
|
|
80
|
+
continue
|
|
81
|
+
out.append(f"### {title}")
|
|
82
|
+
out.append("")
|
|
83
|
+
for short_hash, subject in commits:
|
|
84
|
+
out.append(f"- {subject} ({short_hash})")
|
|
85
|
+
out.append("")
|
|
86
|
+
|
|
87
|
+
if not any(buckets.values()):
|
|
88
|
+
out.append("_No commits in range._")
|
|
89
|
+
out.append("")
|
|
90
|
+
|
|
91
|
+
sys.stdout.write("\n".join(out).rstrip() + "\n")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
main()
|
|
@@ -5,9 +5,22 @@ on:
|
|
|
5
5
|
branches: [main]
|
|
6
6
|
types: [opened, synchronize, reopened, ready_for_review]
|
|
7
7
|
workflow_dispatch:
|
|
8
|
+
# Callable as a gate by release.yml, which passes the pinned release SHA as
|
|
9
|
+
# `ref` so the whole matrix runs against the exact commit being released
|
|
10
|
+
# (not the branch tip). When triggered by a PR, `ref` is empty and every
|
|
11
|
+
# checkout falls back to the triggering ref.
|
|
12
|
+
workflow_call:
|
|
13
|
+
inputs:
|
|
14
|
+
ref:
|
|
15
|
+
description: "Commit SHA / ref to check out. Empty = triggering ref."
|
|
16
|
+
required: false
|
|
17
|
+
type: string
|
|
18
|
+
default: ""
|
|
8
19
|
|
|
9
20
|
concurrency:
|
|
10
|
-
group
|
|
21
|
+
# Distinct group per release ref so a release-triggered run never cancels (or
|
|
22
|
+
# is cancelled by) a PR's CI. PR runs still coalesce per PR number.
|
|
23
|
+
group: ${{ github.workflow }}-${{ inputs.ref || github.event.pull_request.number || github.ref }}
|
|
11
24
|
cancel-in-progress: true
|
|
12
25
|
|
|
13
26
|
jobs:
|
|
@@ -16,10 +29,12 @@ jobs:
|
|
|
16
29
|
strategy:
|
|
17
30
|
fail-fast: false
|
|
18
31
|
matrix:
|
|
19
|
-
os: [ubuntu-latest, macos-latest]
|
|
32
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
20
33
|
runs-on: ${{ matrix.os }}
|
|
21
34
|
steps:
|
|
22
35
|
- uses: actions/checkout@v6
|
|
36
|
+
with:
|
|
37
|
+
ref: ${{ inputs.ref }}
|
|
23
38
|
|
|
24
39
|
- name: Install Rust toolchain
|
|
25
40
|
uses: dtolnay/rust-toolchain@stable
|
|
@@ -43,11 +58,13 @@ jobs:
|
|
|
43
58
|
strategy:
|
|
44
59
|
fail-fast: false
|
|
45
60
|
matrix:
|
|
46
|
-
os: [ubuntu-latest, macos-latest]
|
|
61
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
47
62
|
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
48
63
|
runs-on: ${{ matrix.os }}
|
|
49
64
|
steps:
|
|
50
65
|
- uses: actions/checkout@v6
|
|
66
|
+
with:
|
|
67
|
+
ref: ${{ inputs.ref }}
|
|
51
68
|
|
|
52
69
|
- name: Install Rust toolchain
|
|
53
70
|
uses: dtolnay/rust-toolchain@stable
|
|
@@ -62,23 +79,40 @@ jobs:
|
|
|
62
79
|
with:
|
|
63
80
|
python-version: ${{ matrix.python }}
|
|
64
81
|
|
|
82
|
+
# Create the venv and put its bin/Scripts dir on PATH so the
|
|
83
|
+
# subsequent steps work identically on Unix (.venv/bin) and
|
|
84
|
+
# Windows (.venv/Scripts).
|
|
65
85
|
- name: Create virtualenv
|
|
66
|
-
|
|
86
|
+
shell: bash
|
|
87
|
+
run: |
|
|
88
|
+
python -m venv .venv
|
|
89
|
+
# GITHUB_PATH entries must be native paths. In Git Bash on Windows
|
|
90
|
+
# $PWD is an MSYS path (/d/a/shell/shell) that the runner's Windows
|
|
91
|
+
# PATH cannot resolve, so the venv would be silently ignored and
|
|
92
|
+
# later steps would fall back to the host interpreter. Convert to a
|
|
93
|
+
# native Windows path with cygpath so .venv\Scripts is actually used.
|
|
94
|
+
if [ "$RUNNER_OS" == "Windows" ]; then
|
|
95
|
+
cygpath -w "$PWD/.venv/Scripts" >> "$GITHUB_PATH"
|
|
96
|
+
else
|
|
97
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
98
|
+
fi
|
|
67
99
|
|
|
68
100
|
- name: Install build deps
|
|
69
|
-
run:
|
|
101
|
+
run: pip install maturin pytest
|
|
70
102
|
|
|
71
103
|
- name: Build and install wheel
|
|
72
|
-
run:
|
|
104
|
+
run: maturin develop --release
|
|
73
105
|
|
|
74
106
|
- name: pytest
|
|
75
|
-
run:
|
|
107
|
+
run: pytest tests/python -v
|
|
76
108
|
|
|
77
109
|
audit:
|
|
78
110
|
name: Security audit
|
|
79
111
|
runs-on: ubuntu-latest
|
|
80
112
|
steps:
|
|
81
113
|
- uses: actions/checkout@v6
|
|
114
|
+
with:
|
|
115
|
+
ref: ${{ inputs.ref }}
|
|
82
116
|
|
|
83
117
|
- name: Install Rust toolchain
|
|
84
118
|
uses: dtolnay/rust-toolchain@stable
|
|
@@ -115,11 +149,13 @@ jobs:
|
|
|
115
149
|
strategy:
|
|
116
150
|
fail-fast: false
|
|
117
151
|
matrix:
|
|
118
|
-
os: [ubuntu-latest, macos-latest]
|
|
152
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
119
153
|
node: ["20", "22", "24"]
|
|
120
154
|
runs-on: ${{ matrix.os }}
|
|
121
155
|
steps:
|
|
122
156
|
- uses: actions/checkout@v6
|
|
157
|
+
with:
|
|
158
|
+
ref: ${{ inputs.ref }}
|
|
123
159
|
|
|
124
160
|
- name: Install Rust toolchain
|
|
125
161
|
uses: dtolnay/rust-toolchain@stable
|
|
@@ -134,6 +170,15 @@ jobs:
|
|
|
134
170
|
with:
|
|
135
171
|
node-version: ${{ matrix.node }}
|
|
136
172
|
|
|
173
|
+
# The package.json build scripts use `$(npm run --silent host-triple)`
|
|
174
|
+
# command substitution. npm runs script bodies with its configured
|
|
175
|
+
# script-shell, which defaults to cmd.exe on Windows (no `$(...)`
|
|
176
|
+
# support). Point it at the Git Bash that ships on the windows-latest
|
|
177
|
+
# runner so the substitution works identically across platforms.
|
|
178
|
+
- name: Use bash as npm script-shell (Windows)
|
|
179
|
+
if: runner.os == 'Windows'
|
|
180
|
+
run: npm config set script-shell bash
|
|
181
|
+
|
|
137
182
|
- name: npm install
|
|
138
183
|
# package-lock.json is gitignored, so `npm ci` can't run; use install.
|
|
139
184
|
run: npm install
|