Repository: jetify-com/devbox Branch: main Commit: b589a11e5bef Files: 895 Total size: 1.8 MB Directory structure: gitextract_w04sbmq7/ ├── .envrc ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── 01-bug.yaml │ │ ├── 02-feature.yaml │ │ ├── 03-package-bug.yaml │ │ └── 04-package-request.yaml │ ├── pull_request_template.md │ └── workflows/ │ ├── cache-upload.yml │ ├── cli-post-release.yml │ ├── cli-release.yml │ ├── cli-tests.yaml │ ├── debug.yaml │ ├── docker-image-release.yml │ ├── random-reviewer-assignment.yml │ ├── stale-issue-cleanup.yml │ └── vscode-ext-release.yaml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yaml ├── .schema/ │ ├── devbox-plugin.schema.json │ └── devbox.schema.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NUSHELL.md ├── README.md ├── cmd/ │ └── devbox/ │ └── main.go ├── devbox.go ├── devbox.json ├── devbox.md ├── examples/ │ ├── .gitignore │ ├── README.md │ ├── cloud_development/ │ │ ├── argo-workflows/ │ │ │ ├── README.md │ │ │ ├── argo-patch.sh │ │ │ └── devbox.json │ │ ├── maelstrom/ │ │ │ ├── README.md │ │ │ └── devbox.json │ │ ├── minikube/ │ │ │ ├── README.md │ │ │ └── devbox.json │ │ └── temporal/ │ │ ├── .envrc │ │ ├── .gitignore │ │ ├── README.md │ │ ├── devbox.json │ │ ├── hello/ │ │ │ ├── .gitignore │ │ │ ├── __init__.py │ │ │ ├── hello_activity.py │ │ │ └── hello_cron.py │ │ ├── requirements.txt │ │ ├── tests/ │ │ │ └── __init__.py │ │ └── venvShellHook.sh │ ├── data_science/ │ │ ├── R/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── src/ │ │ │ └── examplePlot.R │ │ ├── README.md │ │ ├── jupyter/ │ │ │ ├── .envrc │ │ │ ├── .pdm-python │ │ │ ├── .pdm.toml │ │ │ ├── __pypackages__/ │ │ │ │ └── .gitignore │ │ │ ├── devbox.json │ │ │ ├── main.py │ │ │ └── pyproject.toml │ │ ├── llama/ │ │ │ ├── README.md │ │ │ └── devbox.json │ │ ├── pytorch/ │ │ │ ├── basic-example/ │ │ │ │ ├── README.md │ │ │ │ ├── devbox.json │ │ │ │ ├── main.py │ │ │ │ └── pyproject.toml │ │ │ └── gradio/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── class_names.txt │ │ │ ├── devbox.json │ │ │ ├── requirements.txt │ │ │ └── run.py │ │ └── tensorflow/ │ │ ├── README.md │ │ ├── devbox.json │ │ ├── main.py │ │ └── requirements.txt │ ├── databases/ │ │ ├── mariadb/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── setup_db.sql │ │ ├── mysql/ │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ ├── mysql/ │ │ │ │ │ └── my.cnf │ │ │ │ ├── mysql80/ │ │ │ │ │ └── my.cnf │ │ │ │ └── mysql84/ │ │ │ │ └── my.cnf │ │ │ ├── devbox.json │ │ │ ├── my.cnf │ │ │ └── setup_db.sql │ │ ├── postgres/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── setup_postgres_db.sql │ │ ├── redis/ │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ └── redis/ │ │ │ │ └── redis.conf │ │ │ └── devbox.json │ │ └── valkey/ │ │ ├── README.md │ │ ├── devbox.d/ │ │ │ └── valkey/ │ │ │ └── valkey.conf │ │ └── devbox.json │ ├── development/ │ │ ├── bun/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── bun.lockb │ │ │ ├── devbox.json │ │ │ ├── index.test.ts │ │ │ ├── index.ts │ │ │ ├── package.json │ │ │ └── tsconfig.json │ │ ├── csharp/ │ │ │ └── hello-world/ │ │ │ ├── .gitignore │ │ │ ├── Program.cs │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── hello-world.csproj │ │ ├── elixir/ │ │ │ └── elixir_hello/ │ │ │ ├── .formatter.exs │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── lib/ │ │ │ │ ├── elixir_hello.ex │ │ │ │ └── kv.exs │ │ │ ├── mix.exs │ │ │ └── test/ │ │ │ ├── elixir_hello_test.exs │ │ │ └── test_helper.exs │ │ ├── fsharp/ │ │ │ └── hello-world/ │ │ │ ├── .gitignore │ │ │ ├── Program.fs │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── hello-world.fsproj │ │ ├── go/ │ │ │ └── hello-world/ │ │ │ ├── .envrc │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── go.mod │ │ │ └── main.go │ │ ├── haskell/ │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── my-project/ │ │ │ ├── .gitignore │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── Setup.hs │ │ │ ├── app/ │ │ │ │ └── Main.hs │ │ │ ├── my-project.cabal │ │ │ ├── package.yaml │ │ │ ├── src/ │ │ │ │ └── Lib.hs │ │ │ ├── stack.yaml │ │ │ └── test/ │ │ │ └── Spec.hs │ │ ├── java/ │ │ │ ├── README.md │ │ │ ├── gradle/ │ │ │ │ ├── .gitignore │ │ │ │ └── hello-world/ │ │ │ │ ├── README.md │ │ │ │ ├── build.gradle │ │ │ │ ├── devbox.json │ │ │ │ ├── gradlew │ │ │ │ ├── settings.gradle │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ └── java/ │ │ │ │ └── hello/ │ │ │ │ └── HelloWorld.java │ │ │ └── maven/ │ │ │ ├── .gitignore │ │ │ └── hello-world/ │ │ │ ├── README.md │ │ │ ├── devbox-maven-app/ │ │ │ │ └── pom.xml │ │ │ ├── devbox.json │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── com/ │ │ │ │ └── devbox/ │ │ │ │ └── mavenapp/ │ │ │ │ └── App.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── devbox/ │ │ │ └── mavenapp/ │ │ │ └── AppTest.java │ │ ├── nim/ │ │ │ └── spinnytest/ │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── spinnytest │ │ │ ├── spinnytest.nim │ │ │ └── spinnytest.nimble │ │ ├── nodejs/ │ │ │ ├── .gitignore │ │ │ ├── nodejs-npm/ │ │ │ │ ├── README.md │ │ │ │ ├── devbox.json │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ │ ├── nodejs-pnpm/ │ │ │ │ ├── README.md │ │ │ │ ├── devbox.json │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ │ ├── nodejs-typescript/ │ │ │ │ ├── .gitignore │ │ │ │ ├── devbox.json │ │ │ │ ├── index.js │ │ │ │ ├── index.ts │ │ │ │ ├── package.json │ │ │ │ └── tsconfig.json │ │ │ └── nodejs-yarn/ │ │ │ ├── .yarnrc.yml │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── php/ │ │ │ └── latest/ │ │ │ ├── .envrc │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ ├── devbox.d/ │ │ │ │ └── php/ │ │ │ │ ├── php-fpm.conf │ │ │ │ └── php.ini │ │ │ ├── devbox.json │ │ │ └── public/ │ │ │ └── index.php │ │ ├── python/ │ │ │ ├── pip/ │ │ │ │ ├── .envrc │ │ │ │ ├── README.md │ │ │ │ ├── devbox.d/ │ │ │ │ │ └── python310Packages.pip/ │ │ │ │ │ └── venvShellHook.sh │ │ │ │ ├── devbox.json │ │ │ │ ├── main.py │ │ │ │ └── requirements.txt │ │ │ ├── pipenv/ │ │ │ │ ├── Pipfile │ │ │ │ ├── README.md │ │ │ │ ├── devbox.json │ │ │ │ ├── main.py │ │ │ │ └── requirements.txt │ │ │ └── poetry/ │ │ │ ├── poetry-demo/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── devbox.json │ │ │ │ ├── poetry_demo/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── __main__.py │ │ │ │ ├── pyproject.toml │ │ │ │ └── tests/ │ │ │ │ ├── __init__.py │ │ │ │ └── test_poetry_demo.py │ │ │ └── poetry-pyproject-subdir/ │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── frontend/ │ │ │ │ └── .empty │ │ │ └── service/ │ │ │ ├── pyproject.toml │ │ │ └── test_with_pytest.py │ │ ├── ruby/ │ │ │ ├── .envrc │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── hello.rb │ │ ├── rust/ │ │ │ ├── README.md │ │ │ └── rust-stable-hello-world/ │ │ │ ├── .gitignore │ │ │ ├── Cargo.toml │ │ │ ├── conf/ │ │ │ │ └── set-env.sh │ │ │ ├── devbox.json │ │ │ └── src/ │ │ │ └── main.rs │ │ └── zig/ │ │ ├── README.md │ │ └── zig-hello-world/ │ │ ├── .gitignore │ │ ├── build.zig │ │ ├── devbox.json │ │ └── src/ │ │ └── main.zig │ ├── flakes/ │ │ ├── README.md │ │ ├── go-mod/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── ory-cli/ │ │ │ └── flake.nix │ │ ├── overlay/ │ │ │ ├── .nvmrc │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── package.json │ │ │ └── yarn-overlay/ │ │ │ └── flake.nix │ │ ├── php/ │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ └── php/ │ │ │ │ ├── php-fpm.conf │ │ │ │ └── php.ini │ │ │ ├── devbox.json │ │ │ └── my-php-flake/ │ │ │ └── flake.nix │ │ ├── php-extension/ │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ └── my-php-flake/ │ │ │ └── flake.nix │ │ └── remote/ │ │ └── devbox.json │ ├── insecure/ │ │ └── devbox.json │ ├── plugins/ │ │ ├── builtin/ │ │ │ ├── devbox.d/ │ │ │ │ └── php84/ │ │ │ │ ├── php-fpm.conf │ │ │ │ └── php.ini │ │ │ └── devbox.json │ │ ├── git/ │ │ │ ├── devbox.d/ │ │ │ │ ├── jetify-com.devbox-plugin-example.my-github-plugin/ │ │ │ │ │ └── some-file.txt │ │ │ │ └── jetpack-io-devbox-plugin-example/ │ │ │ │ └── some-file.txt │ │ │ ├── devbox.json │ │ │ └── test.sh │ │ ├── git-with-revision/ │ │ │ ├── devbox.d/ │ │ │ │ └── jetpack-io-devbox-plugin-example/ │ │ │ │ └── some-file.txt │ │ │ ├── devbox.json │ │ │ └── test.sh │ │ ├── github/ │ │ │ ├── devbox.d/ │ │ │ │ ├── jetify-com.devbox-plugin-example.my-github-plugin/ │ │ │ │ │ └── some-file.txt │ │ │ │ └── jetpack-io-devbox-plugin-example/ │ │ │ │ └── some-file.txt │ │ │ ├── devbox.json │ │ │ └── test.sh │ │ ├── github-with-revision/ │ │ │ ├── devbox.d/ │ │ │ │ └── jetpack-io-devbox-plugin-example/ │ │ │ │ └── some-file.txt │ │ │ ├── devbox.json │ │ │ └── test.sh │ │ ├── local/ │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ └── my-plugin/ │ │ │ │ └── some-file.txt │ │ │ ├── devbox.json │ │ │ ├── my-plugin/ │ │ │ │ ├── plugin.json │ │ │ │ ├── process-compose.yaml │ │ │ │ └── some-file.txt │ │ │ └── test.sh │ │ ├── v2-git/ │ │ │ ├── devbox.d/ │ │ │ │ └── jetpack-io-devbox-plugin-example/ │ │ │ │ └── some-file.txt │ │ │ ├── devbox.json │ │ │ └── test.sh │ │ ├── v2-github/ │ │ │ ├── devbox.d/ │ │ │ │ └── jetpack-io-devbox-plugin-example/ │ │ │ │ └── some-file.txt │ │ │ ├── devbox.json │ │ │ └── test.sh │ │ └── v2-local/ │ │ ├── devbox.d/ │ │ │ └── plugin1/ │ │ │ └── foo.txt │ │ ├── devbox.json │ │ ├── plugin1/ │ │ │ ├── foo.txt │ │ │ ├── plugin.json │ │ │ ├── plugin1a/ │ │ │ │ └── plugin.json │ │ │ └── process-compose.yaml │ │ ├── plugin2/ │ │ │ ├── plugin.json │ │ │ └── process-compose.yaml │ │ └── plugin3/ │ │ └── plugin.json │ ├── servers/ │ │ ├── apache/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ ├── apacheHttpd/ │ │ │ │ │ └── httpd.conf │ │ │ │ └── web/ │ │ │ │ └── index.html │ │ │ └── devbox.json │ │ ├── caddy/ │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ ├── caddy/ │ │ │ │ │ └── Caddyfile │ │ │ │ └── web/ │ │ │ │ └── index.html │ │ │ └── devbox.json │ │ └── nginx/ │ │ ├── .envrc │ │ ├── .gitignore │ │ ├── README.md │ │ ├── devbox.d/ │ │ │ ├── nginx/ │ │ │ │ ├── fastcgi.conf │ │ │ │ ├── nginx.conf │ │ │ │ └── nginx.template │ │ │ └── web/ │ │ │ └── index.html │ │ └── devbox.json │ ├── stacks/ │ │ ├── django/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── process-compose.yml │ │ │ ├── requirements.txt │ │ │ └── todo_project/ │ │ │ ├── manage.py │ │ │ ├── todo_app/ │ │ │ │ ├── __init__.py │ │ │ │ ├── admin.py │ │ │ │ ├── apps.py │ │ │ │ ├── migrations/ │ │ │ │ │ ├── 0001_initial.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── models.py │ │ │ │ ├── templates/ │ │ │ │ │ └── todo_app/ │ │ │ │ │ ├── create_todo.html │ │ │ │ │ └── todo_list.html │ │ │ │ ├── tests.py │ │ │ │ └── views.py │ │ │ └── todo_project/ │ │ │ ├── __init__.py │ │ │ ├── asgi.py │ │ │ ├── settings.py │ │ │ ├── urls.py │ │ │ └── wsgi.py │ │ ├── drupal/ │ │ │ ├── .editorconfig │ │ │ ├── .gitattributes │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ ├── devbox.d/ │ │ │ │ ├── .gitignore │ │ │ │ ├── nginx/ │ │ │ │ │ ├── fastcgi.conf │ │ │ │ │ ├── mime.conf │ │ │ │ │ ├── nginx.conf │ │ │ │ │ └── nginx.template │ │ │ │ └── php/ │ │ │ │ ├── php-fpm.conf │ │ │ │ └── php.ini │ │ │ ├── devbox.json │ │ │ ├── install-drupal.sh │ │ │ ├── setup_db.sql │ │ │ └── web/ │ │ │ ├── .csslintrc │ │ │ ├── .eslintignore │ │ │ ├── .eslintrc.json │ │ │ ├── .gitignore │ │ │ ├── .ht.router.php │ │ │ ├── .htaccess │ │ │ ├── INSTALL.txt │ │ │ ├── README.md │ │ │ ├── example.gitignore │ │ │ ├── index.html │ │ │ ├── index.php │ │ │ ├── modules/ │ │ │ │ └── README.txt │ │ │ ├── profiles/ │ │ │ │ └── README.txt │ │ │ ├── robots.txt │ │ │ ├── sites/ │ │ │ │ ├── README.txt │ │ │ │ ├── default/ │ │ │ │ │ ├── default.services.yml │ │ │ │ │ └── default.settings.php │ │ │ │ ├── development.services.yml │ │ │ │ ├── example.settings.local.php │ │ │ │ └── example.sites.php │ │ │ ├── themes/ │ │ │ │ └── README.txt │ │ │ ├── update.php │ │ │ └── web.config │ │ ├── jekyll/ │ │ │ ├── .envrc │ │ │ ├── README.md │ │ │ ├── devbox.json │ │ │ ├── myblog/ │ │ │ │ ├── .bundle/ │ │ │ │ │ └── config │ │ │ │ ├── .gitignore │ │ │ │ ├── 404.html │ │ │ │ ├── Gemfile │ │ │ │ ├── _config.yml │ │ │ │ ├── _posts/ │ │ │ │ │ └── 2023-01-15-welcome-to-jekyll.markdown │ │ │ │ ├── about.md │ │ │ │ └── index.md │ │ │ └── process-compose.yml │ │ ├── lapp-stack/ │ │ │ ├── .gitignore │ │ │ ├── .testrc │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ ├── apache/ │ │ │ │ │ └── httpd.conf │ │ │ │ ├── php/ │ │ │ │ │ ├── php-fpm.conf │ │ │ │ │ └── php.ini │ │ │ │ └── web/ │ │ │ │ └── index.html │ │ │ ├── devbox.json │ │ │ ├── my_app/ │ │ │ │ ├── config.php │ │ │ │ ├── index.php │ │ │ │ └── info.php │ │ │ └── setup_postgres_db.sql │ │ ├── laravel/ │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ ├── php/ │ │ │ │ │ ├── php-fpm.conf │ │ │ │ │ └── php.ini │ │ │ │ └── redis/ │ │ │ │ └── redis.conf │ │ │ └── devbox.json │ │ ├── lepp-stack/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── devbox.d/ │ │ │ │ ├── nginx/ │ │ │ │ │ ├── fastcgi.conf │ │ │ │ │ ├── nginx.conf │ │ │ │ │ └── nginx.template │ │ │ │ ├── php/ │ │ │ │ │ ├── php-fpm.conf │ │ │ │ │ └── php.ini │ │ │ │ └── web/ │ │ │ │ └── index.html │ │ │ ├── devbox.json │ │ │ ├── my_app/ │ │ │ │ ├── config.php │ │ │ │ ├── index.php │ │ │ │ └── info.php │ │ │ └── setup_postgres_db.sql │ │ ├── rails/ │ │ │ ├── .ruby-version │ │ │ ├── README.md │ │ │ ├── blog/ │ │ │ │ ├── .gitignore │ │ │ │ ├── .ruby-version │ │ │ │ ├── Gemfile │ │ │ │ ├── Rakefile │ │ │ │ ├── app/ │ │ │ │ │ ├── assets/ │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ └── manifest.js │ │ │ │ │ │ ├── images/ │ │ │ │ │ │ │ └── .keep │ │ │ │ │ │ └── stylesheets/ │ │ │ │ │ │ └── application.css │ │ │ │ │ ├── channels/ │ │ │ │ │ │ └── application_cable/ │ │ │ │ │ │ ├── channel.rb │ │ │ │ │ │ └── connection.rb │ │ │ │ │ ├── controllers/ │ │ │ │ │ │ ├── application_controller.rb │ │ │ │ │ │ └── concerns/ │ │ │ │ │ │ └── .keep │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ └── application_helper.rb │ │ │ │ │ ├── jobs/ │ │ │ │ │ │ └── application_job.rb │ │ │ │ │ ├── mailers/ │ │ │ │ │ │ └── application_mailer.rb │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── application_record.rb │ │ │ │ │ │ └── concerns/ │ │ │ │ │ │ └── .keep │ │ │ │ │ └── views/ │ │ │ │ │ └── layouts/ │ │ │ │ │ ├── application.html.erb │ │ │ │ │ ├── mailer.html.erb │ │ │ │ │ └── mailer.text.erb │ │ │ │ ├── bin/ │ │ │ │ │ ├── bundle │ │ │ │ │ ├── rails │ │ │ │ │ ├── rake │ │ │ │ │ └── setup │ │ │ │ ├── config/ │ │ │ │ │ ├── application.rb │ │ │ │ │ ├── boot.rb │ │ │ │ │ ├── cable.yml │ │ │ │ │ ├── credentials.yml.enc │ │ │ │ │ ├── database.yml │ │ │ │ │ ├── environment.rb │ │ │ │ │ ├── environments/ │ │ │ │ │ │ ├── development.rb │ │ │ │ │ │ ├── production.rb │ │ │ │ │ │ └── test.rb │ │ │ │ │ ├── initializers/ │ │ │ │ │ │ ├── assets.rb │ │ │ │ │ │ ├── content_security_policy.rb │ │ │ │ │ │ ├── filter_parameter_logging.rb │ │ │ │ │ │ ├── inflections.rb │ │ │ │ │ │ └── permissions_policy.rb │ │ │ │ │ ├── locales/ │ │ │ │ │ │ └── en.yml │ │ │ │ │ ├── puma.rb │ │ │ │ │ ├── routes.rb │ │ │ │ │ └── storage.yml │ │ │ │ ├── config.ru │ │ │ │ ├── db/ │ │ │ │ │ ├── schema.rb │ │ │ │ │ └── seeds.rb │ │ │ │ ├── lib/ │ │ │ │ │ ├── assets/ │ │ │ │ │ │ └── .keep │ │ │ │ │ └── tasks/ │ │ │ │ │ └── .keep │ │ │ │ ├── log/ │ │ │ │ │ └── .keep │ │ │ │ ├── public/ │ │ │ │ │ ├── 404.html │ │ │ │ │ ├── 422.html │ │ │ │ │ ├── 500.html │ │ │ │ │ └── robots.txt │ │ │ │ ├── storage/ │ │ │ │ │ └── .keep │ │ │ │ ├── test/ │ │ │ │ │ ├── application_system_test_case.rb │ │ │ │ │ ├── channels/ │ │ │ │ │ │ └── application_cable/ │ │ │ │ │ │ └── connection_test.rb │ │ │ │ │ ├── controllers/ │ │ │ │ │ │ └── .keep │ │ │ │ │ ├── fixtures/ │ │ │ │ │ │ └── files/ │ │ │ │ │ │ └── .keep │ │ │ │ │ ├── helpers/ │ │ │ │ │ │ └── .keep │ │ │ │ │ ├── integration/ │ │ │ │ │ │ └── .keep │ │ │ │ │ ├── mailers/ │ │ │ │ │ │ └── .keep │ │ │ │ │ ├── models/ │ │ │ │ │ │ └── .keep │ │ │ │ │ ├── system/ │ │ │ │ │ │ └── .keep │ │ │ │ │ └── test_helper.rb │ │ │ │ └── tmp/ │ │ │ │ ├── .keep │ │ │ │ ├── pids/ │ │ │ │ │ └── .keep │ │ │ │ └── storage/ │ │ │ │ └── .keep │ │ │ ├── devbox.json │ │ │ └── process-compose.yml │ │ └── spring/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build.gradle │ │ ├── devbox.json │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── settings.gradle │ │ ├── setup_db.sql │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── devbox/ │ │ │ │ └── example/ │ │ │ │ └── spring/ │ │ │ │ └── spring/ │ │ │ │ ├── Application.java │ │ │ │ ├── MainController.java │ │ │ │ ├── User.java │ │ │ │ └── UserRepository.java │ │ │ └── resources/ │ │ │ └── application.properties │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── devbox/ │ │ └── example/ │ │ └── spring/ │ │ └── spring/ │ │ └── ApplicationTests.java │ └── tutorial/ │ ├── README.md │ └── devbox.json ├── flake.nix ├── go.mod ├── go.sum ├── internal/ │ ├── boxcli/ │ │ ├── add.go │ │ ├── args.go │ │ ├── auth.go │ │ ├── cache.go │ │ ├── config.go │ │ ├── create.go │ │ ├── env.go │ │ ├── featureflag/ │ │ │ ├── auth.go │ │ │ ├── feature.go │ │ │ ├── feature_test.go │ │ │ ├── impure_print_dev_env.go │ │ │ ├── resolvev2.go │ │ │ ├── script_exit_on_error.go │ │ │ └── tidywarning.go │ │ ├── gen-docs.go │ │ ├── generate.go │ │ ├── global.go │ │ ├── info.go │ │ ├── init.go │ │ ├── install.go │ │ ├── integrate.go │ │ ├── list.go │ │ ├── log.go │ │ ├── midcobra/ │ │ │ ├── debug.go │ │ │ ├── midcobra.go │ │ │ ├── telemetry.go │ │ │ ├── telemetry_test.go │ │ │ └── trace.go │ │ ├── multi/ │ │ │ ├── multi.go │ │ │ └── sync.go │ │ ├── patch.go │ │ ├── path.go │ │ ├── pull.go │ │ ├── push.go │ │ ├── rm.go │ │ ├── root.go │ │ ├── run.go │ │ ├── search.go │ │ ├── secrets.go │ │ ├── services.go │ │ ├── setup.go │ │ ├── shell.go │ │ ├── shellenv.go │ │ ├── update.go │ │ ├── usererr/ │ │ │ ├── exiterr.go │ │ │ └── usererr.go │ │ └── version.go │ ├── build/ │ │ └── build.go │ ├── cachehash/ │ │ ├── hash.go │ │ └── hash_test.go │ ├── cmdutil/ │ │ ├── cmdutil.go │ │ └── exec.go │ ├── conf/ │ │ ├── doc.go │ │ └── env.go │ ├── cuecfg/ │ │ ├── cuecfg.go │ │ ├── doc.go │ │ ├── json.go │ │ ├── toml.go │ │ ├── xml.go │ │ └── yaml.go │ ├── debug/ │ │ ├── debug.go │ │ └── time.go │ ├── devbox/ │ │ ├── cache.go │ │ ├── devbox.go │ │ ├── devbox_test.go │ │ ├── devopt/ │ │ │ └── devboxopts.go │ │ ├── docgen/ │ │ │ ├── docgen.go │ │ │ └── readme.tmpl │ │ ├── envpath/ │ │ │ ├── pathlists.go │ │ │ ├── pathlists_test.go │ │ │ ├── stack.go │ │ │ └── stack_test.go │ │ ├── envvars.go │ │ ├── errors.go │ │ ├── flakes.go │ │ ├── generate/ │ │ │ ├── devcontainer_util.go │ │ │ └── tmpl/ │ │ │ ├── DevboxImageDockerfile │ │ │ ├── DevboxImageDockerfileRootUser │ │ │ ├── Dockerfile.dockerignore.tmpl │ │ │ ├── dev.Dockerfile.tmpl │ │ │ ├── envrc.tmpl │ │ │ ├── envrcContent.tmpl │ │ │ └── prod.Dockerfile.tmpl │ │ ├── global.go │ │ ├── nixprofile.go │ │ ├── packages.go │ │ ├── providers/ │ │ │ ├── identity/ │ │ │ │ └── identity.go │ │ │ └── nixcache/ │ │ │ ├── nixcache.go │ │ │ └── setup.go │ │ ├── pure_shell.go │ │ ├── pushpull.go │ │ ├── refresh.go │ │ ├── secrets.go │ │ ├── services.go │ │ ├── shell.go │ │ ├── shell_test.go │ │ ├── shellcmd/ │ │ │ ├── command.go │ │ │ └── command_test.go │ │ ├── shellrc.tmpl │ │ ├── shellrc_fish.tmpl │ │ ├── testdata/ │ │ │ └── shellrc/ │ │ │ ├── basic/ │ │ │ │ ├── env │ │ │ │ ├── shellrc │ │ │ │ └── shellrc.golden │ │ │ ├── noshellrc/ │ │ │ │ └── shellrc.golden │ │ │ └── zsh_zdotdir/ │ │ │ ├── env │ │ │ ├── shellrc │ │ │ └── shellrc.golden │ │ ├── update.go │ │ ├── update_test.go │ │ └── util.go │ ├── devconfig/ │ │ ├── config.go │ │ ├── config_test.go │ │ ├── configfile/ │ │ │ ├── ast.go │ │ │ ├── env.go │ │ │ ├── field.go │ │ │ ├── file.go │ │ │ ├── file_test.go │ │ │ ├── packages.go │ │ │ ├── packages_test.go │ │ │ └── scripts.go │ │ └── init.go │ ├── devpkg/ │ │ ├── narinfo_cache.go │ │ ├── outputs.go │ │ ├── package.go │ │ ├── package_test.go │ │ ├── pkgtype/ │ │ │ ├── flake.go │ │ │ └── runx.go │ │ └── validation.go │ ├── envir/ │ │ ├── env.go │ │ └── util.go │ ├── fileutil/ │ │ ├── dir.go │ │ ├── fileutil.go │ │ ├── fileutil_test.go │ │ └── untar.go │ ├── goutil/ │ │ ├── goutil.go │ │ └── sync.go │ ├── lock/ │ │ ├── interfaces.go │ │ ├── lockfile.go │ │ ├── package.go │ │ ├── resolve.go │ │ └── statehash.go │ ├── nix/ │ │ ├── build.go │ │ ├── cache.go │ │ ├── command.go │ │ ├── config.go │ │ ├── config_test.go │ │ ├── doc.go │ │ ├── eval.go │ │ ├── flake.go │ │ ├── install.go │ │ ├── install_test.go │ │ ├── instance.go │ │ ├── nix.go │ │ ├── nix_test.go │ │ ├── nixpkgs.go │ │ ├── nixprofile/ │ │ │ ├── item.go │ │ │ ├── profile.go │ │ │ ├── profile_test.go │ │ │ └── upgrade.go │ │ ├── profiles.go │ │ ├── run.go │ │ ├── search.go │ │ ├── search_test.go │ │ ├── shim.go │ │ ├── store.go │ │ ├── store_test.go │ │ ├── storepath.go │ │ ├── storepath_test.go │ │ ├── upgrade.go │ │ └── writer.go │ ├── patchpkg/ │ │ ├── builder.go │ │ ├── elf.go │ │ ├── glibc-patch.bash │ │ ├── patch.go │ │ └── search.go │ ├── plugin/ │ │ ├── files.go │ │ ├── git.go │ │ ├── git_test.go │ │ ├── github.go │ │ ├── github_test.go │ │ ├── includable.go │ │ ├── includes.go │ │ ├── info.go │ │ ├── local.go │ │ ├── manager.go │ │ ├── plugin.go │ │ ├── rm.go │ │ ├── services.go │ │ └── update.go │ ├── pullbox/ │ │ ├── config.go │ │ ├── download.go │ │ ├── files.go │ │ ├── git/ │ │ │ ├── git.go │ │ │ └── push.go │ │ ├── pullbox.go │ │ ├── s3/ │ │ │ ├── config.go │ │ │ ├── pull.go │ │ │ └── push.go │ │ └── tar/ │ │ └── tar.go │ ├── redact/ │ │ ├── redact.go │ │ └── redact_test.go │ ├── searcher/ │ │ ├── client.go │ │ ├── model.go │ │ ├── parse.go │ │ └── parse_test.go │ ├── services/ │ │ ├── client.go │ │ ├── config.go │ │ ├── manager.go │ │ ├── ports.go │ │ ├── services.go │ │ └── status.go │ ├── setup/ │ │ ├── setup.go │ │ └── setup_test.go │ ├── shellgen/ │ │ ├── doc.go │ │ ├── flake_input.go │ │ ├── flake_plan.go │ │ ├── flake_plan_test.go │ │ ├── generate.go │ │ ├── generate_test.go │ │ ├── nixpkgs.go │ │ ├── path.go │ │ ├── scripts.go │ │ ├── testdata/ │ │ │ ├── flake-empty.nix.golden │ │ │ └── flake.nix.golden │ │ └── tmpl/ │ │ ├── .gitignore.tmpl │ │ ├── flake.nix.tmpl │ │ ├── glibc-patch.nix.tmpl │ │ ├── script-wrapper.tmpl │ │ └── shell.nix.tmpl │ ├── telemetry/ │ │ ├── segment.go │ │ ├── sentry.go │ │ ├── telemetry.go │ │ └── telemetry_test.go │ ├── templates/ │ │ ├── template.go │ │ ├── templates.go │ │ └── templates_test.go │ ├── ux/ │ │ └── messages.go │ ├── vercheck/ │ │ ├── vercheck.go │ │ └── vercheck_test.go │ └── xdg/ │ └── xdg.go ├── nix/ │ ├── command.go │ ├── flake/ │ │ ├── flakeref.go │ │ └── flakeref_test.go │ ├── install.go │ ├── nix.go │ └── nix_test.go ├── pkg/ │ └── autodetect/ │ ├── autodetect.go │ └── detector/ │ ├── detector.go │ ├── go.go │ ├── go_test.go │ ├── nodejs.go │ ├── nodejs_test.go │ ├── php.go │ ├── php_test.go │ ├── poetry.go │ └── python.go ├── plugins/ │ ├── README.md │ ├── apache/ │ │ ├── httpd.conf │ │ └── process-compose.yaml │ ├── apacheHttpd.json │ ├── builtins.go │ ├── builtins_test.go │ ├── caddy/ │ │ ├── Caddyfile │ │ └── process-compose.yaml │ ├── caddy.json │ ├── elixir.json │ ├── gradle.json │ ├── haskell/ │ │ └── flake.nix │ ├── haskell.json │ ├── mariadb/ │ │ ├── flake.nix │ │ ├── my.cnf │ │ ├── process-compose.yaml │ │ └── setup_db.sh │ ├── mariadb.json │ ├── mysql/ │ │ ├── flake.nix │ │ ├── my.cnf │ │ ├── process-compose.yaml │ │ └── setup_db.sh │ ├── mysql.json │ ├── nginx/ │ │ ├── fastcgi.conf │ │ ├── nginx.conf │ │ ├── nginx.template │ │ └── process-compose.yaml │ ├── nginx.json │ ├── nodejs.json │ ├── php/ │ │ ├── flake.nix │ │ ├── php-fpm.conf │ │ ├── php.ini │ │ └── process-compose.yaml │ ├── php.json │ ├── poetry/ │ │ └── initHook.sh │ ├── poetry.json │ ├── postgresql/ │ │ └── process-compose.yaml │ ├── postgresql.json │ ├── python/ │ │ └── venvShellHook.sh │ ├── python.json │ ├── redis/ │ │ ├── process-compose.yaml │ │ └── redis.conf │ ├── redis.json │ ├── ruby.json │ ├── rustc.json │ ├── rustup.json │ ├── valkey/ │ │ ├── process-compose.yaml │ │ └── valkey.conf │ ├── valkey.json │ └── web/ │ └── index.html ├── scripts/ │ └── gofumpt.sh ├── testscripts/ │ ├── Dockerfile │ ├── README.md │ ├── add/ │ │ ├── add.test.txt │ │ ├── add_insecure.tst.txt │ │ ├── add_outputs.test.txt │ │ ├── add_platforms.test.txt │ │ ├── add_platforms_flakeref.test.txt │ │ ├── add_replace.test.txt │ │ └── global_add.test.txt │ ├── assert/ │ │ └── assert.test.txt │ ├── basic/ │ │ ├── default_test_env.test.txt │ │ ├── install_hello.test.txt │ │ └── path_whitespace.test.txt │ ├── generate/ │ │ ├── devcontainer.test.txt │ │ ├── direnv-config-envflag.test.txt │ │ ├── direnv-config.test.txt │ │ ├── direnv-envflag.test.txt │ │ ├── direnv-envrcdir-config-parent.test.txt │ │ ├── direnv-envrcdir-config-sibling.test.txt │ │ ├── direnv-envrcdir-config-subdir-envflag.test.txt │ │ ├── direnv-envrcdir-config-subdir.test.txt │ │ ├── direnv-envrcdir-current-config-sub.test.txt │ │ ├── direnv-envrcdir-fail-no-config.test.txt │ │ ├── direnv-envrcdir-parent-no-config.test.txt │ │ ├── direnv-envrcdir-parent.test.txt │ │ ├── direnv-envrcdir.test.txt │ │ ├── direnv-printenvrc-config.test.txt │ │ ├── direnv-printenvrc-envrcdir.test.txt │ │ ├── direnv-printenvrc.test.txt │ │ ├── direnv.test.txt │ │ └── dockerfile.test.txt │ ├── info/ │ │ └── info.test.txt │ ├── init/ │ │ └── empty.test.txt │ ├── languages/ │ │ ├── php.test.txt │ │ ├── python_patch_cuda.test.txt │ │ ├── python_patch_missing_ref.test.txt │ │ ├── python_patch_missing_so.test.txt │ │ └── python_patch_old_glibc.test.txt │ ├── lockfile/ │ │ ├── lockfile_tidy.test.txt │ │ └── nopaths.txt │ ├── packages/ │ │ ├── flakes.test.txt │ │ └── unfree.test.txt │ ├── plugin/ │ │ ├── disable-plugin.test.txt │ │ ├── plugin.cycle.test.txt │ │ └── plugin.test.txt │ ├── rm/ │ │ ├── add-rm.test.txt │ │ ├── manual.test.txt │ │ ├── multi.test.txt │ │ └── rm.test.txt │ ├── run/ │ │ ├── args.test.txt │ │ ├── env.test.txt │ │ ├── envfrom.test.txt │ │ ├── path.test.txt │ │ ├── pure.test.txt │ │ ├── quote_escaping.test.txt │ │ ├── script.test.txt │ │ ├── script_exit_on_error.test.txt │ │ └── shellception.test.txt │ ├── shell/ │ │ └── shellenv.test.txt │ ├── shellenv/ │ │ └── node/ │ │ ├── README.md │ │ ├── devbox.json │ │ ├── less-out/ │ │ │ └── style.css │ │ ├── less-src/ │ │ │ └── style.less │ │ └── package.json │ ├── testrunner/ │ │ ├── assert.go │ │ ├── examplesrunner.go │ │ ├── run_test.test.txt │ │ ├── setupenv.go │ │ ├── source.go │ │ ├── testrunner.go │ │ └── updater/ │ │ └── main.go │ ├── testscripts_test.go │ └── update/ │ └── update.test.txt ├── typos.toml ├── vendor-hash └── vscode-extension/ ├── .eslintrc.json ├── .gitignore ├── .vscodeignore ├── .yarnrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── package.json ├── src/ │ ├── devbox.ts │ ├── extension.ts │ ├── openinvscode.ts │ └── test/ │ ├── runTest.ts │ └── suite/ │ ├── extension.test.ts │ └── index.ts └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .envrc ================================================ #!/usr/bin/env bash # Automatically sets up your devbox environment whenever you cd into this # directory via our direnv integration: eval "$(devbox generate direnv --print-envrc)" # check out https://www.jetify.com/docs/devbox/ide_configuration/direnv/ # for more details ================================================ FILE: .gitattributes ================================================ *.go diff=golang *.sh diff=bash *.md diff=markdown *.py diff=python *.sql diff=sql devbox.json linguist-language=json5 go.sum -diff linguist-generated ================================================ FILE: .github/ISSUE_TEMPLATE/01-bug.yaml ================================================ name: Bug Report description: File a bug report labels: - bug - triage body: - type: textarea id: description attributes: label: What happened? description: >- Also include what you expected to happen and any other relevant details. validations: required: true - type: textarea id: repro attributes: label: Steps to reproduce description: >- What specific steps can we take to reproduce this issue? Including a script would be much appreciated! value: | 1. 2. 3. - type: dropdown id: commands attributes: label: Command description: What Devbox command were you running when the bug occurred? multiple: true options: - add - auth - create - generate - global - info - init - install - rm - run - search - services - shell - shellenv - update - version - type: textarea id: devbox-json attributes: label: devbox.json description: Please include a copy of your devbox.json file. render: "jsonc" - type: input id: devbox-version attributes: label: Devbox version description: "Paste the output of `devbox version`." validations: required: true - type: input id: nix-version attributes: label: Nix version description: "Paste the output of `nix --version`." - type: dropdown id: system attributes: label: What system does this bug occur on? options: - macOS (Intel) - macOS (Apple Silicon) - Linux (x86-64) - Linux (ARM64) - Other (please include in the description above) validations: required: true - type: textarea id: logs attributes: label: Debug logs description: >- If possible, reproduce the bug with the `DEVBOX_DEBUG=1` environment variable set and paste any output here. For example: `DEVBOX_DEBUG=1 devbox run -- mycrash.sh`. ================================================ FILE: .github/ISSUE_TEMPLATE/02-feature.yaml ================================================ name: Feature Request description: Suggest an idea or new feature labels: - feature - triage body: - type: textarea id: problem attributes: label: What problem are you trying to solve? description: >- Describe the problem you're trying to solve with this feature. placeholder: I'm always frustrated when... validations: required: true - type: textarea id: solution attributes: label: What solution would you like? description: >- Describe the feature you would like to see implemented and explain how it would address the problem you described above. validations: required: true - type: textarea id: alternatives attributes: label: Alternatives you've considered description: >- Describe any alternative solutions or features you've considered. If you know of any similar features requested before, please include links to them. ================================================ FILE: .github/ISSUE_TEMPLATE/03-package-bug.yaml ================================================ name: Package Issue description: Report a problem with an existing package on either Devbox or Nixhub labels: - package - bug - triage body: - type: input id: name attributes: label: Package name placeholder: go@1.21.6, python@3.10.13, etc. validations: required: true - type: textarea id: solution attributes: label: What changes are you requesting? description: >- Describe what's going wrong or what changes you'd like to see to the package. validations: required: true - type: input id: link attributes: label: Nixhub link placeholder: https://www.nixhub.io/packages/go ================================================ FILE: .github/ISSUE_TEMPLATE/04-package-request.yaml ================================================ name: Package Request description: Request a new package to be added to Devbox and Nixhub labels: - package - triage body: - type: input id: name attributes: label: Package name description: What name are you requesting for the new package? validations: required: true - type: input id: nixpkgs attributes: label: Nix package link description: >- Are you able to find the package on https://search.nixos.org/packages? If so, please include a link to the search results. Otherwise, leave blank. - type: textarea id: software attributes: label: Software description: >- Provide a description of the software that should be added to the new package. Include any relevant links such as websites, GitHub repositories, etc. validations: required: true ================================================ FILE: .github/pull_request_template.md ================================================ ## Summary ## How was it tested? ## Community Contribution License All community contributions in this pull request are licensed to the project maintainers under the terms of the [Apache 2 License](https://www.apache.org/licenses/LICENSE-2.0). By creating this pull request, I represent that I have the right to license the contributions to the project maintainers under the Apache 2 License as stated in the [Community Contribution License](https://github.com/jetify-com/opensource/blob/main/CONTRIBUTING.md#community-contribution-license). ================================================ FILE: .github/workflows/cache-upload.yml ================================================ name: cache-upload # Uploads devbox nix dependencies to cache on: push: branches: - main workflow_dispatch: schedule: - cron: '30 8 * * *' # Run nightly at 8:30 UTC permissions: contents: read pull-requests: read defaults: run: shell: bash env: DEVBOX_API_TOKEN: ${{ secrets.DEVBOX_API_TOKEN }} DEVBOX_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} DEVBOX_DEBUG: 1 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # I think this should be added to individual nix commands within devbox, but this is quick fix for now NIX_CONFIG: | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} jobs: upload-cache: strategy: matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} timeout-minutes: 10 steps: - uses: actions/checkout@v4 # Build devbox from scratch because released devbox has a bug that prevents # DEVBOX_API_TOKEN use # we can remove this after 0.10.6 is out. - uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Build devbox run: | go build -o dist/devbox ./cmd/devbox sudo mv ./dist/devbox /usr/local/bin/ # - name: Install devbox # uses: jetify-com/devbox-install-action@v0.14.0 # with: # enable-cache: true # We upload twice, once before updating and once after. This shows a simple # method to cache the latest current and latest dependencies. # If we want read access to cache on multi-user nix installs (e.g. macos), # we need to call devbox cache configure. This is currently not working # as expected on CICD. - name: Upload cache run: | devbox cache upload devbox update devbox cache upload ================================================ FILE: .github/workflows/cli-post-release.yml ================================================ name: cli-post-release # Finalize and announce the release once its been published on Github. on: release: types: [released] permissions: contents: write pull-requests: read id-token: write # Needed for aws-actions/configure-aws-credentials@v1 jobs: publish: runs-on: ubuntu-latest environment: release steps: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: ${{ secrets.AWS_ROLE }} aws-region: us-west-2 - name: Update latest version in s3 run: | tmp_file=$(mktemp) echo "${{ github.ref_name }}" > $tmp_file aws s3 cp $tmp_file s3://releases.jetpack.io/devbox/stable/version ================================================ FILE: .github/workflows/cli-release.yml ================================================ name: cli-release # Releases the Devbox CLI concurrency: cli-release on: # Build/Release on demand workflow_dispatch: inputs: create_edge_release: description: "Create edge release?" required: false default: false type: boolean schedule: - cron: "45 8 * * 4" # Create edge weekly on Thursdays. push: tags: - "*" # Tags that trigger a new release version permissions: contents: write pull-requests: read id-token: write # Needed for aws-actions/configure-aws-credentials@v1 jobs: tests: uses: ./.github/workflows/cli-tests.yaml report-test-failures: runs-on: ubuntu-latest needs: tests if: failure() || cancelled() steps: - name: Notify jetpack.io slack of release status (only if tests fail) id: slack uses: slackapi/slack-github-action@v1.25.0 with: payload: | { "status": "test ${{ needs.tests.result }}" } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLI_RELEASE_WEBHOOK_URL }} edge: runs-on: ubuntu-latest environment: release needs: tests if: ${{ inputs.create_edge_release || github.event.schedule }} steps: - name: Checkout source code uses: actions/checkout@v4 with: fetch-depth: 0 # Needed by goreleaser to browse history. - name: Determine edge tag # This tag is semver and works with semver.Compare run: echo "EDGE_TAG=0.0.0-edge.$(date +%Y-%m-%d)" >> $GITHUB_ENV - name: Set edge tag id: tag_version uses: mathieudutour/github-tag-action@v6.1 with: github_token: ${{ secrets.GITHUB_TOKEN }} custom_tag: ${{ env.EDGE_TAG }} tag_prefix: "" - name: Set up go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Build snapshot with goreleaser uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser version: latest args: release --clean --skip=announce,publish --snapshot env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TELEMETRY_KEY: ${{ secrets.TELEMETRY_KEY }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - name: Create Sentry release uses: getsentry/action-release@v1 env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG: ${{ vars.SENTRY_ORG }} SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} with: environment: development version: ${{ env.EDGE_TAG }} version_prefix: "devbox@" - name: Publish snapshot release to GitHub uses: softprops/action-gh-release@v1 with: prerelease: true body: "${{ env.EDGE_TAG }} edge release" fail_on_unmatched_files: true tag_name: ${{ env.EDGE_TAG }} files: | dist/checksums.txt dist/*.tar.gz - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: ${{ secrets.AWS_ROLE }} aws-region: us-west-2 - name: Update edge version in s3 run: | tmp_file=$(mktemp) echo "${{ env.EDGE_TAG }}" > $tmp_file aws s3 cp $tmp_file s3://releases.jetpack.io/devbox/edge/version release: runs-on: ubuntu-latest environment: release needs: tests # Only release when there's a tag for the release. if: startsWith(github.ref, 'refs/tags/') steps: - name: Checkout source code uses: actions/checkout@v4 with: fetch-depth: 0 # Needed by goreleaser to browse history. - name: Set up go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Create Sentry release uses: getsentry/action-release@v1 env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG: ${{ vars.SENTRY_ORG }} SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} with: environment: production version: ${{ github.ref }} version_prefix: "devbox@" - name: Release with goreleaser uses: goreleaser/goreleaser-action@v3 with: distribution: goreleaser version: latest args: release --clean env: DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }} DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TELEMETRY_KEY: ${{ secrets.TELEMETRY_KEY }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - name: Notify jetpack.io slack of release status id: slack if: always() uses: slackapi/slack-github-action@v1.25.0 with: payload: | { "status": "release ${{ job.status }}" } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLI_RELEASE_WEBHOOK_URL }} ================================================ FILE: .github/workflows/cli-tests.yaml ================================================ name: cli-tests # Runs the Devbox CLI tests concurrency: group: ${{ github.ref }} cancel-in-progress: true on: pull_request: push: branches: - main merge_group: branches: - main workflow_call: inputs: run-mac-tests: type: boolean workflow_dispatch: inputs: run-mac-tests: type: boolean description: Run tests on macOS example-debug: type: boolean description: Run example tests with DEVBOX_DEBUG=1 to increase verbosity schedule: - cron: '30 8 * * *' # Run nightly at 8:30 UTC permissions: contents: read pull-requests: read defaults: run: # Explicitly setting the shell to bash runs commands with # `bash --noprofile --norc -eo pipefail` instead of `bash -e`. shell: bash env: DEVBOX_DEBUG: 1 DEVBOX_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} HOMEBREW_NO_ANALYTICS: 1 HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_EMOJI: 1 HOMEBREW_NO_ENV_HINTS: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1 NIX_CONFIG: | access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} jobs: build-devbox: strategy: matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Build devbox run: go build -o dist/devbox ./cmd/devbox - name: Upload devbox artifact uses: actions/upload-artifact@v4 with: name: devbox-${{ runner.os }}-${{ runner.arch }} path: ./dist/devbox retention-days: 7 typos: name: Spell Check with Typos if: github.ref != 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: crate-ci/typos@v1.16.26 flake-test: name: Test Flake Build if: github.ref != 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install devbox uses: jetify-com/devbox-install-action@jl/migrate-installer with: enable-cache: true - name: Build flake run: | if ! devbox run build-flake; then echo "::warning::If this fails, you probably have to run 'devbox run update-hash'" exit 1 fi - run: ./result/bin/devbox version golangci-lint: strategy: matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} timeout-minutes: 10 steps: - uses: actions/checkout@v4 - name: Install devbox uses: jetify-com/devbox-install-action@jl/migrate-installer with: enable-cache: true - name: Mount golang cache uses: actions/cache@v4 with: path: | ~/.cache/golangci-lint ~/.cache/go-build ~/go/pkg key: go-${{ runner.os }}-${{ hashFiles('go.sum') }} - run: devbox run lint test: needs: build-devbox strategy: matrix: is-main: - ${{ github.ref == 'refs/heads/main' && 'is-main' || 'not-main' }} os: [ubuntu-latest, macos-latest] # This is an optimization that runs tests twice, with and without # the devbox.json tests. We can require the other tests to complete before # merging, while keeping the others as an additional non-required signal run-project-tests: ["project-tests-only", "project-tests-off"] # Run tests on: # 1. the oldest supported nix version (Nixpkgs requires >= 2.18 as of 2026) # 2. nix 2.19.2: version before nix profile changes # 3. latest nix version (note, 2.20.1 introduced a new profile change) nix-version: ["2.18.0", "2.19.2", "2.30.2"] exclude: # Only runs tests on macos if explicitly requested, or on a schedule - os: "${{ (inputs.run-mac-tests || github.event.schedule != '') && 'dummy' || 'macos-latest' }}" runs-on: ${{ matrix.os }} timeout-minutes: 60 env: # For devbox.json tests, we default to non-debug mode since the debug output is less useful than for unit testscripts. # But we allow overriding via inputs.example-debug DEVBOX_DEBUG: ${{ (matrix.run-project-tests == 'project-tests-off' || inputs.example-debug) && '1' || '0' }} DEVBOX_GOLANG_TEST_TIMEOUT: "${{ (github.ref == 'refs/heads/main' || inputs.run-mac-tests) && '1h' || '30m' }}" steps: - name: clear directories to reduce disk usage # https://github.com/actions/runner-images/issues/2840#issuecomment-1284059930 run: | sudo rm -rf /usr/share/dotnet sudo rm -rf "$AGENT_TOOLSDIRECTORY" - uses: actions/checkout@v4 - name: Mount golang cache uses: actions/cache@v4 with: path: | ~/.cache/go-build ~/go/pkg key: go-devbox-tests-${{ runner.os }}-${{ hashFiles('go.sum') }} - name: Install additional shells (dash, zsh) run: | if [ "$RUNNER_OS" == "Linux" ]; then sudo apt-get update sudo apt-get install dash zsh elif [ "$RUNNER_OS" == "macOS" ]; then brew update brew install dash zsh fi - name: Install devbox uses: jetify-com/devbox-install-action@jl/migrate-installer with: enable-cache: true - name: Setup Nix GitHub authentication run: | # Setup github authentication to ensure Github's rate limits are not hit # For macOS, we need to configure the system-wide nix.conf because the Nix daemon # runs as a different user and doesn't read the user's ~/.config/nix/nix.conf if [ "$RUNNER_OS" == "macOS" ]; then echo "Configuring system-wide Nix config for macOS daemon" # Ensure /etc/nix directory exists if [ ! -d /etc/nix ]; then sudo mkdir -p /etc/nix fi # Check if file exists, create it if not if [ ! -f /etc/nix/nix.conf ]; then echo "# Nix configuration" | sudo tee /etc/nix/nix.conf > /dev/null fi echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" | sudo tee -a /etc/nix/nix.conf # Restart nix daemon to pick up the new configuration sudo launchctl stop org.nixos.nix-daemon || true sudo launchctl start org.nixos.nix-daemon || true sleep 2 # Give daemon time to restart fi # For Linux and as a backup for macOS, also configure user config mkdir -p ~/.config/nix echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" > ~/.config/nix/nix.conf - name: Run fast tests if: matrix.run-project-tests == 'project-tests-off' run: | echo "::group::Nix version" nix --version echo "::endgroup::" echo "::group::Contents of /etc/nix/nix.conf" cat /etc/nix/nix.conf || true echo "::endgroup::" echo "::group::Resolved Nix config" nix show-config --extra-experimental-features nix-command echo "::endgroup::" devbox run go test -v -timeout $DEVBOX_GOLANG_TEST_TIMEOUT ./... - name: Run project (slow) tests if: matrix.run-project-tests == 'project-tests-only' run: devbox run test-projects-only auto-nix-install: # ensure Devbox installs nix and works properly after installation. needs: build-devbox strategy: matrix: os: [ubuntu-latest, macos-latest] use-detsys: [true, false] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Download devbox uses: actions/download-artifact@v4 with: name: devbox-${{ runner.os }}-${{ runner.arch }} - name: Add devbox to path run: | chmod +x ./devbox sudo mv ./devbox /usr/local/bin/ - name: Install nix and devbox packages run: | export NIX_INSTALLER_NO_CHANNEL_ADD=1 export DEVBOX_FEATURE_DETSYS_INSTALLER=${{ matrix.use-detsys }} # Setup github authentication BEFORE running devbox to ensure Github's rate limits are not hit. # Configure user config first (Nix installer will respect this) mkdir -p ~/.config/nix echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" > ~/.config/nix/nix.conf # Run devbox which will auto-install Nix if needed devbox run echo "Installing packages..." # After Nix is installed, configure system-wide config for the daemon on macOS if [ "$RUNNER_OS" == "macOS" ]; then echo "Configuring system-wide Nix config for macOS daemon" # Check if file exists, create directory if needed if [ ! -f /etc/nix/nix.conf ]; then sudo mkdir -p /etc/nix echo "# Nix configuration" | sudo tee /etc/nix/nix.conf > /dev/null fi echo "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" | sudo tee -a /etc/nix/nix.conf # Restart nix daemon to pick up the new configuration sudo launchctl stop org.nixos.nix-daemon || true sudo launchctl start org.nixos.nix-daemon || true sleep 2 # Give daemon time to restart fi - name: Test removing package run: devbox rm go # Run a sanity test to make sure Devbox can install and remove packages with # the last few Nix releases. test-nix-versions: needs: build-devbox strategy: matrix: os: [ubuntu-latest, macos-latest] nix-version: [2.18.0, 2.19.2, 2.24.7, 2.30.2] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Download devbox uses: actions/download-artifact@v4 with: name: devbox-${{ runner.os }}-${{ runner.arch }} - name: Add devbox to path run: | chmod +x ./devbox sudo mv ./devbox /usr/local/bin/ - name: Install Nix uses: DeterminateSystems/nix-installer-action@v4 with: logger: pretty extra-conf: experimental-features = ca-derivations fetch-closure nix-package-url: https://releases.nixos.org/nix/nix-${{ matrix.nix-version }}/nix-${{ matrix.nix-version }}-${{ runner.arch == 'X64' && 'x86_64' || 'aarch64' }}-${{ runner.os == 'macOS' && 'darwin' || 'linux' }}.tar.xz - name: Run devbox install, devbox run, devbox rm run: | echo "::group::Nix version" nix --version echo "::endgroup::" echo "::group::Contents of /etc/nix/nix.conf" cat /etc/nix/nix.conf || true echo "::endgroup::" echo "::group::Resolved Nix config" nix show-config --extra-experimental-features nix-command echo "::endgroup::" devbox install devbox run -- echo "Hello from devbox!" devbox rm go ================================================ FILE: .github/workflows/debug.yaml ================================================ name: debug on: workflow_dispatch: inputs: runner: description: "Runner type to debug on" required: true default: "ubuntu-latest" type: choice options: - macos-latest - ubuntu-latest permissions: contents: read env: HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}" HOMEBREW_NO_ANALYTICS: 1 HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_EMOJI: 1 HOMEBREW_NO_ENV_HINTS: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1 jobs: debug: runs-on: ${{ inputs.runner }} timeout-minutes: 10 steps: - name: Get rate limits run: | curl https://api.github.com/rate_limit \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ --show-error \ --silent \ | jq . - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version-file: ./go.mod - run: | echo "Starting a tmate session for 10 minutes." echo echo "You can connect using the SSH command printed below to get an interactive shell" echo "on this GitHub Actions runner. Access is limited to the public SSH keys" echo "associated with your GitHub account." curl https://api.github.com/users/${{ github.actor }}/keys \ -H "Accept: application/vnd.github+json" \ --show-error \ --silent \ | jq . - uses: mxschmitt/action-tmate@v3 with: limit-access-to-actor: true ================================================ FILE: .github/workflows/docker-image-release.yml ================================================ name: docker-image-release on: release: types: - published workflow_dispatch: inputs: tag: description: 'tag name' required: true default: '' type: string jobs: docker-image-build-push: runs-on: ubuntu-latest steps: - name: Check out the repo uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Docker meta id: meta uses: docker/metadata-action@v5 with: images: | jetpackio/devbox tags: | type=raw,value=${{ inputs.tag || github.ref_name }} flavor: | latest=false - name: Docker meta root id: metaroot uses: docker/metadata-action@v5 with: images: | jetpackio/devbox-root-user tags: | type=raw,value=${{ inputs.tag || github.ref_name }} flavor: | latest=false - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Build and push default uses: docker/build-push-action@v5 with: context: ./internal/devbox/generate/tmpl/ file: ./internal/devbox/generate/tmpl/DevboxImageDockerfile build-args: | DEVBOX_USE_VERSION=${{ inputs.tag || github.ref_name }} push: true platforms: linux/amd64,linux/arm64 tags: ${{ steps.meta.outputs.tags }} - name: Build and push root user uses: docker/build-push-action@v5 with: context: ./internal/devbox/generate/tmpl/ file: ./internal/devbox/generate/tmpl/DevboxImageDockerfileRootUser build-args: | DEVBOX_USE_VERSION=${{ inputs.tag || github.ref_name }} push: true platforms: linux/amd64,linux/arm64 tags: ${{ steps.metaroot.outputs.tags }} - name: Docker meta latest id: metalatest uses: docker/metadata-action@v5 with: images: | jetpackio/devbox tags: | type=raw,value=latest flavor: | latest=true - name: Build and push latest uses: docker/build-push-action@v5 with: context: ./internal/devbox/generate/tmpl/ file: ./internal/devbox/generate/tmpl/DevboxImageDockerfile push: true platforms: linux/amd64,linux/arm64 tags: ${{ steps.metalatest.outputs.tags }} - name: Docker meta root latest id: metarootlatest uses: docker/metadata-action@v5 with: images: | jetpackio/devbox-root-user tags: | type=raw,value=latest flavor: | latest=true - name: Build and push root user latest uses: docker/build-push-action@v5 with: context: ./internal/devbox/generate/tmpl/ file: ./internal/devbox/generate/tmpl/DevboxImageDockerfileRootUser push: true platforms: linux/amd64,linux/arm64 tags: ${{ steps.metarootlatest.outputs.tags }} ================================================ FILE: .github/workflows/random-reviewer-assignment.yml ================================================ name: Random Reviewer Assignment on: pull_request: types: [opened] permissions: contents: read pull-requests: write env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN_FOR_PR_ASSIGNMENT }} jobs: assign-reviewer: runs-on: ubuntu-latest steps: - name: Randomly assign reviewer from team uses: actions/github-script@v6 with: script: | const TRIAGE_USERNAME = 'Lagoja'; const EXCLUDE_USERNAMES = ['jetpack-io-bot']; try { const authenticatedUser = await github.rest.users.getAuthenticated(); const teamMembers = await github.rest.teams.listMembersInOrg({ org: 'jetify-com', team_slug: 'eng' }); const prAuthor = context.payload.pull_request.user.login.toLowerCase(); const prAuthorId = context.payload.pull_request.user.id; const authenticatedUserLower = authenticatedUser.data.login.toLowerCase(); // If the PR author is already a member of the team, we can skip random assignment const isPrAuthorInTeam = teamMembers.data.some(member => member.login.toLowerCase() === prAuthor && member.id === prAuthorId ); if (isPrAuthorInTeam) { console.log(`PR author ${prAuthor} is already a team member, skipping random assignment.`); return; } // Get eligible reviewers (excluding PR author, authenticated user, and lagoja) const eligibleReviewers = teamMembers.data .filter(member => { const loginLower = member.login.toLowerCase(); // Exclude authenticated user const isNotAuthenticatedUser = member.id !== authenticatedUser.data.id; const isNotTriage = loginLower !== TRIAGE_USERNAME.toLowerCase(); const isNotExcludedUsername = !EXCLUDE_USERNAMES.includes(loginLower); return isNotAuthenticatedUser && isNotTriage && isNotExcludedUsername; }) .map(member => member.login); console.log(`Eligible reviewers: ${eligibleReviewers.join(', ')}`); if (eligibleReviewers.length === 0) { console.log('No eligible reviewers found'); return; } const randomReviewer = eligibleReviewers[Math.floor(Math.random() * eligibleReviewers.length)]; const reviewers = [randomReviewer]; // Only add TRIAGE_USERNAME if they're not the PR author and not the authenticated user if (prAuthor !== TRIAGE_USERNAME.toLowerCase() && authenticatedUserLower !== TRIAGE_USERNAME.toLowerCase()) { reviewers.push(TRIAGE_USERNAME); } console.log(`Final reviewers: ${reviewers.join(', ')}`); console.log(`Assigning reviewers: ${reviewers.join(', ')}`); await github.rest.pulls.requestReviewers({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.payload.pull_request.number, reviewers }); } catch (error) { console.error('Error assigning reviewer:', error); } ================================================ FILE: .github/workflows/stale-issue-cleanup.yml ================================================ name: close-stale-issues # Marks issues and PRs as stale after 30 days, then closes them if marked stale for 5 days on: schedule: - cron: '30 1 * * *' jobs: stale: runs-on: ubuntu-latest steps: - uses: actions/stale@v7 with: stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove the `stale` label or add a comment, otherwise this issue will be closed in 5 days.' stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Remove the `stale` label or add a comment, otherwise this PR will be closed in 5 days.' exempt-issue-labels: 'future' exempt-pr-labels: 'awaiting-approval, work-in-progress' days-before-stale: 45 days-before-close: 5 operations: 100 ================================================ FILE: .github/workflows/vscode-ext-release.yaml ================================================ name: vscode-ext-release # Releases the Devbox VSCode extension to the marketplace concurrency: vscode-ext-release on: workflow_dispatch jobs: build-publish: runs-on: ubuntu-latest environment: release steps: - name: Checkout uses: actions/checkout@v5 - name: Setup NodeJS 24 uses: actions/setup-node@v5 with: node-version: 24 - name: Install dependencies run: | npm install -g yarn npm install -g vsce npm install -g ovsx yarn install working-directory: vscode-extension - name: publish-vs run: | vsce publish -p ${{ secrets.VS_MARKETPLACE_TOKEN }} --yarn --skip-duplicate working-directory: vscode-extension - name: publish-ovsx run: | sed -i 's/"publisher": "jetpack-io"/"publisher": "Jetify"/g' package.json ovsx publish --pat ${{ secrets.OVSX_MARKETPLACE_TOKEN }} --yarn --skip-duplicate working-directory: vscode-extension ================================================ FILE: .gitignore ================================================ # Global gitignore for the entire monorepo. Only add things here that truly # need to always be ignored regardless of project. # # If something is more specific to a particular project, add a gitignore in the # corresponding subdirectory. # MacOS filesystem .DS_Store # Editors .idea .vscode .zed # NodeJS node_modules .yalc dist # Python *.pyc __pycache__/ *.py[cod] *$py.class # Java *.class *.jar # devcontainer *.devcontainer # test specific files .test_tmp_* # deployment .vercel .yarn # Nix vendor/ result ================================================ FILE: .golangci.yml ================================================ linters: disable-all: true enable: - dupl - errcheck - errorlint - gofmt - goimports - gosimple - govet - importas - ineffassign - misspell - nilerr - reassign - revive - staticcheck - stylecheck - typecheck - unconvert - unparam - unused - usestdlibvars - usetesting - varnamelen # - wrapcheck If we're going to use github.com/pkg/errors we should probably turn this on? # We'd like to have the following linter enabled, but it's broken for Go # 1.19 as of golangci-lint v1.48.0. Re-enable it when this issue is # fixed: https://github.com/golangci/golangci-lint/issues/2649 # - structcheck linters-settings: errorlint: errorf: false revive: rules: # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md - name: atomic - name: bare-return - name: bool-literal-in-expr - name: cognitive-complexity exclude: - "**_test.go" arguments: - 32 # TODO: gradually reduce it - name: datarace - name: duplicated-imports - name: early-return - name: error-return - name: error-strings - name: if-return - name: indent-error-flow - name: range-val-address - name: receiver-naming - name: time-naming - name: var-naming - name: unreachable-code varnamelen: max-distance: 10 ignore-decls: - a []any - c echo.Context - const C - e error - e watch.Event - f *foo.Bar - f fmt.State - i int - id string - m map[string]any - m map[string]int - n int - ns string - ok bool - r *http.Request - r io.Reader - r *os.File - re *regexp.Regexp - sh *Shell - sh *shell - sh *shell.Shell - sh shell - T any - t testing.T - w http.ResponseWriter - w io.Writer - w *os.File wrapcheck: ignorePackageGlobs: - go.jetify.com/devbox/* misspell: ignore-words: - substituters ================================================ FILE: .goreleaser.yaml ================================================ project_name: devbox before: hooks: - go mod tidy builds: - main: ./cmd/devbox/main.go binary: devbox flags: - -trimpath mod_timestamp: "{{ .CommitTimestamp }}" # For reproducible builds ldflags: - -s -w - -X go.jetify.com/devbox/internal/build.Version={{.Version}} - -X go.jetify.com/devbox/internal/build.Commit={{.Commit}} - -X go.jetify.com/devbox/internal/build.CommitDate={{.CommitDate}} - -X go.jetify.com/devbox/internal/build.SentryDSN={{ .Env.SENTRY_DSN }} - -X go.jetify.com/devbox/internal/build.TelemetryKey={{ .Env.TELEMETRY_KEY }} env: - CGO_ENABLED=0 - GO111MODULE=on goos: - linux - darwin goarch: - 386 - amd64 - arm64 - arm goarm: - 7 archives: - files: - no-files-will-match-* # Glob that does not match to create archive with only binaries. name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if eq .Arch "arm" }}v{{ .Arm }}l{{ end }}' snapshot: name_template: "{{ .Env.EDGE_TAG }}" checksum: name_template: "checksums.txt" algorithm: sha256 release: prerelease: auto draft: true github: owner: jetify-com name: devbox announce: discord: # Whether its enabled or not. # Defaults to false. enabled: false # Message template to use while publishing. # Defaults to `{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}` message_template: | **New Release: Devbox {{.Tag}}** We just released a version {{.Tag}} of `devbox`. Description: {{.TagBody}} Release: {{.ReleaseURL}} Updating: If you installed devbox via our recommended installer (`curl -fsSL https://get.jetpack.io/devbox | bash`) you will get the new version _automatically_, the next time you run `devbox` Thanks, jetpack.io # Set author of the embed. # Defaults to `GoReleaser` author: "jetpack.io" # Color code of the embed. You have to use decimal numeral system, not hexadecimal. # Defaults to `3888754` - the grey-ish from goreleaser color: "2622553" #This is the Jetpack Space color # URL to an image to use as the icon for the embed. # Defaults to `https://goreleaser.com/static/avatar.png` icon_url: "" ================================================ FILE: .schema/devbox-plugin.schema.json ================================================ { "$schema": "https://json-schema.org/draft-04/schema#", "$id": "https://github.com/jetify-com/devbox/plugins", "title": "Devbox Plugin Schema", "description": "Defines fields and values for public devbox plugins", "type": "object", "properties": { "$schema": { "description": "The schema version of this plugin file.", "type": "string" }, "name": { "description": "The name of the plugin.", "type": "string" }, "version": { "description": "The version of the plugin.", "type": "string" }, "description": { "description": "A short description of the plugin and how it works. This will automatically display when the user first installs the plugin, or runs `devbox info`", "type": "string" }, "packages": { "description": "Collection of packages to install", "oneOf": [ { "type": "array", "items": { "description": "Name and version of each package in name@version format.", "type": "string" } }, { "type": "object", "description": "Name of each package in {\"name\": {\"version\": \"1.2.3\"}} format.", "patternProperties": { ".*": { "oneOf": [ { "type": "object", "description": "Version number of the specified package in {\"version\": \"1.2.3\"} format.", "properties": { "version": { "type": "string", "description": "Version of the package" }, "platforms": { "type": "array", "description": "Names of platforms to install the package on. This package will be skipped for any platforms not on this list", "items": { "enum": [ "i686-linux", "aarch64-linux", "aarch64-darwin", "x86_64-darwin", "x86_64-linux", "armv7l-linux" ] } }, "excluded_platforms": { "type": "array", "description": "Names of platforms to exclude the package on", "items": { "enum": [ "i686-linux", "aarch64-linux", "aarch64-darwin", "x86_64-darwin", "x86_64-linux", "armv7l-linux" ] } }, "glibc_patch": { "type": "boolean", "description": "Whether to patch glibc to the latest available version for this package" } } }, { "type": "string", "description": "Version of the package to install." } ] } } } ] }, "env": { "type": "object", "description": "List of additional environment variables to be set in the Devbox environment. These can be overridden by environment variables set in the user's devbox.json", "patternProperties": { ".*": { "type": "string", "description": "Value of the environment variable." } } }, "create_files": { "type": "object", "description": "List of files to create in the user's project directory when the plugin is activated. The key points to the file path where the file will be created. The value points to the default file that should be copied to that location", "patternProperties": { ".*": { "type": "string", "description": "Contents of the file." } } }, "shell": { "type": "object", "description": "Shell specific options and hooks for the plugin.", "items": { "init_hook": { "type": ["array", "string"], "description": "Shell command to run right before initializing the user's shell, running a script, or starting a service" }, "scripts": { "description": "List of command/script definitions to run with `devbox run `.", "type": "object", "patternProperties": { ".*": { "description": "Alias name for the script.", "type": ["array", "string"], "items": { "type": "string", "description": "The script's shell commands." } } } } } }, "include": { "description": "List of additional plugins to activate within your devbox shell", "type": "array", "items": { "description": "Name of the plugin to activate.", "type": "string" } } }, "required": ["name", "version", "description"] } ================================================ FILE: .schema/devbox.schema.json ================================================ { "$schema": "http://json-schema.org/draft-04/schema#", "$id": "https://github.com/jetify-com/devbox", "title": "Devbox json definition", "description": "Defines fields and acceptable values of devbox.json", "type": "object", "properties": { "$schema": { "description": "The schema version of this devbox.json file.", "type": "string" }, "name": { "description": "The name of the Devbox development environment.", "type": "string" }, "description": { "description": "A description of the Devbox development environment.", "type": "string" }, "packages": { "description": "Collection of packages to install", "oneOf": [ { "type": "array", "items": { "description": "Name and version of each package in name@version format.", "type": "string" } }, { "type": "object", "description": "Name of each package in {\"name\": {\"version\": \"1.2.3\"}} format.", "patternProperties": { ".*": { "oneOf": [ { "type": "object", "description": "Version number of the specified package in {\"version\": \"1.2.3\"} format.", "properties": { "version": { "type": "string", "description": "Version of the package" }, "platforms": { "type": "array", "description": "Names of platforms to install the package on. This package will be skipped for any platforms not on this list", "items": { "enum": [ "i686-linux", "aarch64-linux", "aarch64-darwin", "x86_64-darwin", "x86_64-linux", "armv7l-linux" ] } }, "excluded_platforms": { "type": "array", "description": "Names of platforms to exclude the package on", "items": { "enum": [ "i686-linux", "aarch64-linux", "aarch64-darwin", "x86_64-darwin", "x86_64-linux", "armv7l-linux" ] } }, "glibc_patch": { "type": "boolean", "description": "Whether to patch glibc to the latest available version for this package" } } }, { "type": "string", "description": "Version of the package to install." } ] } } } ] }, "env": { "description": "List of additional environment variables to be set in the Devbox environment. Values containing $PATH or $PWD will be expanded. No other variable expansion or command substitution will occur.", "type": "object", "patternProperties": { ".*": { "type": "string", "description": "Value of the environment variable." } } }, "shell": { "description": "Definitions of scripts and actions to take when in devbox shell.", "type": "object", "properties": { "init_hook": { "type": [ "array", "string" ], "items": { "description": "List of shell commands/scripts to run right after devbox shell starts.", "type": "string" } }, "scripts": { "description": "List of command/script definitions to run with `devbox run `.", "type": "object", "patternProperties": { ".*": { "description": "Alias name for the script.", "type": [ "array", "string" ], "items": { "type": "string", "description": "The script's shell commands." } } } } }, "additionalProperties": false }, "include": { "description": "List of additional plugins to activate within your devbox shell", "type": "array", "items": { "description": "Name of the plugin to activate.", "type": "string" } }, "env_from": { "type": "string" }, "nixpkgs": { "type": "object", "properties": { "commit": { "type": "string", "description": "The commit hash of the nixpkgs repository to use" } } } }, "additionalProperties": false } ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: - Demonstrating empathy and kindness toward other people - Being respectful of differing opinions, viewpoints, and experiences - Giving and gracefully accepting constructive feedback - Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience - Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: - The use of sexualized language or imagery, and sexual attention or advances of any kind - Trolling, insulting or derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or email address, without their explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement. Use the "Report to repository admins" functionality on GitHub to report. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][mozilla coc]. For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][faq]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html [mozilla coc]: https://github.com/mozilla/diversity [faq]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing When contributing to this repository, please describe the change you wish to make via a related issue, or a pull request. Please note we have a [code of conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. ## Setting Up Development Environment Before making any changes to the source code (documentation excluded) make sure you have installed all the required tools. ### With Devbox The easiest way to develop Devbox is with Devbox! 1. Install Devbox: curl -fsSL https://get.jetify.com/devbox | bash 2. Clone this repository: git clone https://github.com/jetify-com/devbox.git go.jetify.com/devbox cd go.jetify.com/devbox 3. Build the Devbox CLI. If you don't have Nix installed, Devbox will automatically install it for you before building: devbox run build 4. Start a development shell using your build of Devbox: dist/devbox shell Tip: you can also start VSCode from inside your Devbox shell with `devbox run code`. - If you encounter an error similar to: `line 3: command 'code' not found`, it means you do not have the Visual Studio Code "Shell Command" installed. Follow the official guide at https://code.visualstudio.com/docs/setup/mac. Please refer to the section under: "Launching from the command line". ### Setting up the Environment Without Devbox If you are unable to install or use Devbox, you can manually replicate the environment by following the steps below. 1. Install Nix Package Manager. We recommend using the [Determinate Systems installer](https://github.com/DeterminateSystems/nix-installer): curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install Alternatively, you can also use [the official installer](https://nixos.org/download.html). 2. Install [Go](https://go.dev/doc/install) (current version: 1.20) 3. Clone this repository and build Devbox: git clone https://github.com/jetify-com/devbox.git go.jetify.com/devbox cd go.jetify.com/devbox go build ./cmd/devbox ./devbox run -- echo hello, world ## Pull Request Process 1. For new features or non-trivial changes, consider first filing an issue to discuss what changes you intend to make. This will let us help you with implementation details and to make sure we don't duplicate any work. 2. Ensure any new feature or functionality includes tests to verify its correctness. 3. Run `devbox run lint` and `devbox run test`. 4. Run `go mod tidy` if you added any new dependencies. 5. Submit your pull request and someone will take a look! ### Style Guide We don't expect you to read through a long style guide or be an expert in Go before contributing. When necessary, a reviewer will be happy to help out with any suggestions around code style when you submit your PR. Otherwise, the Devbox codebase generally follows common Go idioms and patterns: - If you're unfamiliar with idiomatic Go, [Effective Go](https://go.dev/doc/effective_go) and the [Google Go Style Guide](https://google.github.io/styleguide/go) are good resources. - There's no strict commit message format, but a good practice is to start the subject with the name of the Go packages you add/modified. For example, `boxcli: update help for add command`. ## Community Contribution License Contributions made to this project must be made under the terms of the [Apache 2 License](https://www.apache.org/licenses/LICENSE-2.0). ``` By making a contribution to this project, you certify that: a. The contribution was created in whole or in part by you and you have the right to submit it under the Apache 2 License; or b. The contribution is based upon previous work that, to the best of your knowledge, is covered under an appropriate open source license and you have the right under that license to submit that work with modifications, whether created in whole or in part by you, under the Apache 2 License; or c. The contribution was provided directly to you by some other person who certified (a), (b) or (c) and you have not modified it. d. You understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information you submit with it, including your sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: NUSHELL.md ================================================ # Using Devbox with Nushell Devbox now supports [nushell](https://github.com/nushell/nushell) through the `--format` flag on the `shellenv` command. ## Quick Start **Add this to `~/.config/nushell/env.nu`:** ```nushell devbox global shellenv --format nushell --preserve-path-stack -r | lines | parse "$env.{name} = \"{value}\"" | where name != null | transpose -r | into record | load-env ``` This is equivalent to bash's `eval "$(devbox global shellenv)"` and runs on every fresh shell start. --- ## Global Configuration To use devbox global packages with nushell, you need to load the environment similar to how bash/zsh use `eval "$(devbox global shellenv)"`. ### Dynamic loading with `load-env` - eval equivalent Add this to `~/.config/nushell/env.nu` to regenerate and load devbox environment fresh every time, just like bash's `eval`: ```nushell # Load devbox global environment dynamically (equivalent to bash eval) devbox global shellenv --format nushell --preserve-path-stack -r | lines | parse "$env.{name} = \"{value}\"" | where name != null | transpose -r | into record | load-env ``` - `--format nushell` - Output in nushell syntax - `--preserve-path-stack` - Maintain existing PATH order if devbox is already active - `-r` (recompute) - Always recompute the environment, prevents "out of date" warnings ================================================ FILE: README.md ================================================ Devbox logo. # Devbox ### Instant, easy, and predictable development environments [![Join Discord](https://img.shields.io/discord/903306922852245526?color=7389D8&label=discord&logo=discord&logoColor=ffffff&cacheSeconds=1800)](https://discord.gg/jetify) ![License: Apache 2.0](https://img.shields.io/github/license/jetify-com/devbox) [![version](https://img.shields.io/github/v/release/jetify-com/devbox?color=green&label=version&sort=semver)](https://github.com/jetify-com/devbox/releases) [![tests](https://github.com/jetify-com/devbox/actions/workflows/cli-post-release.yml/badge.svg)](https://github.com/jetify-com/devbox/actions/workflows/cli-release.yml?branch=main) [![Built with Devbox](https://www.jetify.com/img/devbox/shield_galaxy.svg)](https://www.jetify.com/devbox/docs/contributor-quickstart/) ## What is it? [Devbox](https://www.jetify.com/devbox/) is a command-line tool that lets you easily create isolated shells for development. You start by defining the list of packages required by your development environment, and devbox uses that definition to create an isolated environment just for your application. In practice, Devbox works similar to a package manager like `yarn` – except the packages it manages are at the operating-system level (the sort of thing you would normally install with `brew` or `apt-get`). With Devbox, you can install over [400,000 package versions](https://www.nixhub.io) from the Nix Package Registry Devbox was originally developed by [Jetify](https://www.jetify.com) and is internally powered by `nix`. ## Demo The example below creates a development environment with `python 2.7` and `go 1.18`, even though those packages are not installed in the underlying machine: ![screen cast](https://user-images.githubusercontent.com/279789/186491771-6b910175-18ec-4c65-92b0-ed1a91bb15ed.svg) ## Installing Devbox Use the following install script to get the latest version of Devbox: ```sh curl -fsSL https://get.jetify.com/devbox | bash ``` Read more on the [Devbox docs](https://www.jetify.com/devbox/docs/installing-devbox/). ## Benefits ### A consistent shell for everyone on the team Declare the list of tools needed by your project via a `devbox.json` file and run `devbox shell`. Everyone working on the project gets a shell environment with the exact same version of those tools. ### Try new tools without polluting your laptop Development environments created by Devbox are isolated from everything else in your laptop. Is there a tool you want to try without making a mess? Add it to a Devbox shell, and remove it when you don't want it anymore – all while keeping your laptop pristine. ### Don't sacrifice speed Devbox can create isolated environments right on your laptop, without an extra-layer of virtualization slowing your file system or every command. When you're ready to ship, it'll turn it into an equivalent container – but not before. ### Goodbye conflicting versions Are you working on multiple projects, all of which need different versions of the same binary? Instead of attempting to install conflicting versions of the same binary on your laptop, create an isolated environment for each project, and use whatever version you want for each. ### Take your environment with you Devbox's dev environments are _portable_. We make it possible to declare your environment exactly once, and use that single definition in several different ways, including: - A local shell created through `devbox shell` - A devcontainer you can use with VSCode - A Dockerfile so you can build a production image with the exact same tools you used for development. - A remote development environment in the cloud that mirrors your local environment. ## Quickstart: Fast, Deterministic Shell In this quickstart we'll create a development shell with specific tools installed. These tools will only be available when using this Devbox shell, ensuring we don't pollute your machine. 1. Open a terminal in a new empty folder. 2. Initialize Devbox: ```bash devbox init ``` This creates a `devbox.json` file in the current directory. You should commit it to source control. 3. Add command-line tools from Nix. For example, to add Python 3.10: ```bash devbox add python@3.10 ``` Search for more packages on [Nixhub.io](https://www.nixhub.io) 4. Your `devbox.json` file keeps track of the packages you've added, it should now look like this: ```json { "packages": [ "python@3.10" ] } ``` 5. Start a new shell that has these tools installed: ```bash devbox shell ``` You can tell you're in a Devbox shell (and not your regular terminal) because the shell prompt changed. 6. Use your favorite tools. In this example we installed Python 3.10, so let's use it. ```bash python --version ``` 7. Your regular tools are also available including environment variables and config settings. ```bash git config --get user.name ``` 8. To exit the Devbox shell and return to your regular shell: ```bash exit ``` Read more on the [Devbox docs Quickstart](https://www.jetify.com/devbox/docs/quickstart/). ## Additional commands `devbox help` - see all commands See the [CLI Reference](https://www.jetify.com/devbox/docs/cli_reference/devbox/) for the full list of commands. ## Join our Developer Community - Chat with us by joining the [Jetify Discord Server](https://discord.gg/jetify) – we have a #devbox channel dedicated to this project. - File bug reports and feature requests using [Github Issues](https://github.com/jetify-com/devbox/issues) - Follow us on [Jetify's Twitter](https://twitter.com/jetify_com) for product updates ## Contributing Devbox is an opensource project, so contributions are always welcome. Please read [our contributing guide](CONTRIBUTING.md) before submitting pull requests. [Devbox development readme](devbox.md) ## Related Work Thanks to [Nix](https://nixos.org/) for providing isolated shells. ## License This project is proudly open-source under the [Apache 2.0 License](https://github.com/jetify-com/devbox/blob/main/LICENSE) ================================================ FILE: cmd/devbox/main.go ================================================ // Copyright 2024 Jetify Inc. and contributors. All rights reserved. // Use of this source code is governed by the license in the LICENSE file. package main import ( "go.jetify.com/devbox/internal/boxcli" ) func main() { boxcli.Main() } ================================================ FILE: devbox.go ================================================ // Package devbox creates and configures Devbox development environments. package devbox import ( "context" "io" "go.jetify.com/devbox/internal/devbox" "go.jetify.com/devbox/internal/devbox/devopt" ) // Devbox is a Devbox development environment. type Devbox struct { dx *devbox.Devbox } // Open loads a Devbox environment from a config file or directory. func Open(path string) (*Devbox, error) { dx, err := devbox.Open(&devopt.Opts{ Dir: path, Stderr: io.Discard, }) if err != nil { return nil, err } return &Devbox{dx: dx}, nil } // Install downloads and installs missing packages. func (d *Devbox) Install(ctx context.Context) error { return d.dx.Install(ctx) } ================================================ FILE: devbox.json ================================================ { "name": "devbox", "description": "Instant, easy, and predictable development environments", "packages": { "fd": "latest", "git": "latest", "go": "latest" }, "env": { "GOENV": "off", "PATH": "$PWD/dist/tools:$PATH:$PWD/dist", // Disabling CGO is a workaround for a clang linker error in macos // This should be okay, because Devbox doesn't require CGO // https://github.com/NixOS/nixpkgs/issues/433688#issuecomment-3231557942 "CGO_ENABLED": "0", }, "shell": { "init_hook": [ // Remove Go environment variables that might've been inherited from the // user's environment and could affect the build. "test -z $FISH_VERSION && \\", "unset GO111MODULE GOARCH GOFLAGS GOMOD GOOS GOROOT GOTOOLCHAIN GOWORK || \\", "set --erase GO111MODULE GOARCH GOFLAGS GOMOD GOOS GOROOT GOTOOLCHAIN GOWORK", "GOBIN=$PWD/dist/tools go install tool" ], "scripts": { // Build devbox for the current platform "build": "go build -o dist/devbox ./cmd/devbox", "build-darwin-amd64": "GOOS=darwin GOARCH=amd64 go build -o dist/devbox-darwin-amd64 ./cmd/devbox", "build-darwin-arm64": "GOOS=darwin GOARCH=arm64 go build -o dist/devbox-darwin-arm64 ./cmd/devbox", "build-linux-amd64": "GOOS=linux GOARCH=amd64 go build -o dist/devbox-linux-amd64 ./cmd/devbox", "build-linux-arm64": "GOOS=linux GOARCH=arm64 go build -o dist/devbox-linux-arm64 ./cmd/devbox", "build-all": [ "devbox run build-darwin-amd64", "devbox run build-darwin-arm64", "devbox run build-linux-amd64", "devbox run build-linux-arm64" ], // Open VSCode "code": "code .", "lint": "go tool golangci-lint run --timeout 5m && scripts/gofumpt.sh", "fmt": "scripts/gofumpt.sh", "test": "go test -race -cover ./...", "test-projects-only": "DEVBOX_RUN_PROJECT_TESTS=1 go test -v -timeout ${DEVBOX_GOLANG_TEST_TIMEOUT:-30m} ./... -run \"TestExamples|TestScriptsWithProjects\"", "update-examples": "devbox run build && go run testscripts/testrunner/updater/main.go", // Updates the Flake's vendorHash: First run `go mod vendor` to vendor // the dependencies, then hash the vendor directory with Nix. // The hash is saved to the `vendor-hash` file, which is then // read into the Nix Flake. "update-hash": [ // realpath to work-around nix hash not liking symlinks "vendor=$(realpath $(mktemp -d))", "trap \"rm -rf $vendor\" EXIT", "go mod vendor -o $vendor", "nix hash path $vendor >vendor-hash" ], "build-flake": "nix build .", "tidy": ["go mod tidy", "devbox run update-hash"], // docker-testscripts runs the testscripts with Docker to exercise // Linux-specific tests. It invokes the test binary directly, so any extra // test runner flags must have their "-test." prefix. // // For example, to only run Python tests: // // devbox run docker-testscripts -test.run ^TestScripts$/python "docker-testscripts": [ "cd testscripts", // The Dockerfile looks for a testscripts-$TARGETOS-$TARGETARCH binary // to run the tests. Pre-compiling a static test binary lets us avoid // polluting the container with a Go toolchain or shared libraries that // might interfere with linker tests. "trap 'rm -f testscripts-linux-amd64 testscripts-linux-arm64' EXIT", "GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -c -o testscripts-linux-amd64", "GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go test -c -o testscripts-linux-arm64", "image=$(docker build --quiet --tag devbox-testscripts-ubuntu:noble --platform linux/amd64 .)", "docker run --rm --mount type=volume,src=devbox-testscripts-amd64,dst=/nix --platform linux/amd64 -e DEVBOX_RUN_FAILING_TESTS -e DEVBOX_RUN_PROJECT_TESTS -e DEVBOX_DEBUG $image \"$@\"" ] } } } ================================================ FILE: devbox.md ================================================ # devbox Instant, easy, and predictable development environments ## Getting Started This project uses [devbox](https://github.com/jetify-com/devbox) to manage its development environment. Install devbox: ```sh curl -fsSL https://get.jetify.com/devbox | bash ``` Start the devbox shell: ```sh devbox shell ``` Run a script in the devbox environment: ```sh devbox run