-
Notifications
You must be signed in to change notification settings - Fork 6
feat(sandbox): add environment variable support #111
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
a2be486
feat(sandbox): add environment variable support
amir-at-bunny d8a62ca
fix(sandbox): strip inline comments from unquoted dotenv values
amir-at-bunny 9d14480
refactor(sandbox): rename withSshEnv callback param to procEnv to avo…
amir-at-bunny 70431c8
fix(sandbox): guard reserved env keys at create time
amir-at-bunny 5878460
fix(sandbox): use Object.hasOwn to guard prototype-inherited keys in …
amir-at-bunny 29bfc79
fix(sandbox): use /bin/bash in SSH session bootstrap to avoid PATH in…
amir-at-bunny 2b1c59d
fix(sandbox): error on json delete when no variables removed
amir-at-bunny 86230f8
fix(sandbox): drop -e alias from exec to avoid hijacking remote flags
amir-at-bunny 2649a6b
style(sandbox): organize imports and format sandbox.test.ts
amir-at-bunny File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| --- | ||
| "@bunny.net/sandbox": minor | ||
| "@bunny.net/cli": minor | ||
| --- | ||
|
|
||
| feat(sandbox): add environment variable support | ||
|
|
||
| - SDK: `Sandbox` gains `getEnv`/`setEnv`/`unsetEnv` to read and persist container env vars after creation (merges with the existing set, preserves reserved keys). | ||
| - CLI: `sandbox create`, `sandbox exec`, and `sandbox ssh` accept `-e/--env KEY=VALUE` (repeatable) and `--env-file`. Vars on `create` are persisted; on `exec`/`ssh` they are temporary for that invocation. | ||
| - CLI: new `sandbox env` namespace (`set`/`list`/`delete`) to manage persisted env vars. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| import { describe, expect, test } from "bun:test"; | ||
| import { collectEnv, parseDotenv, splitPair } from "./env-args.ts"; | ||
| import { envPrefix } from "./ssh-exec.ts"; | ||
|
|
||
| describe("splitPair", () => { | ||
| test("splits on the first =", () => { | ||
| expect(splitPair("URL=http://x?a=b")).toEqual(["URL", "http://x?a=b"]); | ||
| }); | ||
|
|
||
| test("allows empty values", () => { | ||
| expect(splitPair("EMPTY=")).toEqual(["EMPTY", ""]); | ||
| }); | ||
|
|
||
| test("rejects entries without =", () => { | ||
| expect(() => splitPair("NOPE")).toThrow("Expected KEY=VALUE"); | ||
| }); | ||
|
|
||
| test("rejects invalid key names", () => { | ||
| expect(() => splitPair("1BAD=x")).toThrow("Invalid environment variable"); | ||
| expect(() => splitPair("has-dash=x")).toThrow(); | ||
| }); | ||
| }); | ||
|
|
||
| describe("parseDotenv", () => { | ||
| test("parses lines, comments, quotes and export", () => { | ||
| const env = parseDotenv( | ||
| [ | ||
| "# comment", | ||
| "", | ||
| "A=1", | ||
| "export B=two", | ||
| `C="quoted value"`, | ||
| "D='single'", | ||
| " E = spaced ", | ||
| ].join("\n"), | ||
| ); | ||
| expect(env).toEqual({ | ||
| A: "1", | ||
| B: "two", | ||
| C: "quoted value", | ||
| D: "single", | ||
| E: "spaced", | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe("collectEnv", () => { | ||
| test("entries override the env file (file loaded first)", async () => { | ||
| // No env file here; just confirm entries merge in order. | ||
| const env = await collectEnv(["A=1", "B=2", "A=3"]); | ||
| expect(env).toEqual({ A: "3", B: "2" }); | ||
| }); | ||
|
|
||
| test("returns an empty object with no inputs", async () => { | ||
| expect(await collectEnv()).toEqual({}); | ||
| }); | ||
| }); | ||
|
|
||
| describe("envPrefix", () => { | ||
| test("builds a shell-quoted assignment prefix", () => { | ||
| expect(envPrefix({ A: "1", B: "two words" })).toBe("A='1' B='two words' "); | ||
| }); | ||
|
|
||
| test("escapes single quotes in values", () => { | ||
| expect(envPrefix({ A: "it's" })).toBe("A='it'\\''s' "); | ||
| }); | ||
|
|
||
| test("is empty when there are no vars", () => { | ||
| expect(envPrefix({})).toBe(""); | ||
| }); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
The new create-time env forwarding allows
--env AGENT_TOKEN=...to reach sandbox provisioning, while the SDK generates its own agent token for SSH and latersetEnvexplicitly reservesAGENT_TOKEN. Passing it at creation sends a duplicate or overridingAGENT_TOKENto Magic Containers, which can leave the container using a different SSH token than the one saved locally. Apply the same reserved-key check before forwarding create env vars.Useful? React with 👍 / 👎.