{"id":26576616,"url":"https://github.com/getsentry/devenv","last_synced_at":"2025-03-23T03:23:50.177Z","repository":{"id":191536142,"uuid":"684262623","full_name":"getsentry/devenv","owner":"getsentry","description":"unified dev environment management tool","archived":false,"fork":false,"pushed_at":"2025-01-29T22:59:53.000Z","size":374,"stargazers_count":9,"open_issues_count":12,"forks_count":2,"subscribers_count":30,"default_branch":"main","last_synced_at":"2025-03-22T06:47:06.424Z","etag":null,"topics":["dev-infra","development-environment","tag-production"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/getsentry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://sentry.io/pricing/","https://sentry.io/"]}},"created_at":"2023-08-28T19:29:19.000Z","updated_at":"2025-03-16T17:33:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"6f0e0bef-980b-4017-b5b7-717f54e157eb","html_url":"https://github.com/getsentry/devenv","commit_stats":null,"previous_names":["getsentry/devenv"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fdevenv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fdevenv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fdevenv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getsentry%2Fdevenv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/getsentry","download_url":"https://codeload.github.com/getsentry/devenv/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245049842,"owners_count":20552734,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dev-infra","development-environment","tag-production"],"created_at":"2025-03-23T03:23:49.619Z","updated_at":"2025-03-23T03:23:50.156Z","avatar_url":"https://github.com/getsentry.png","language":"Python","funding_links":["https://sentry.io/pricing/","https://sentry.io/"],"categories":[],"sub_categories":[],"readme":"## devenv\n\nmanaging dev environments since '24\n\n`devenv` is an extensible execution framework and library for authoring\na simple set of high level commands - bootstrap, sync, doctor, nuke - that\nmanage a repository's dev environment.\n\n## prerequisites\n\nAre you a Sentry employee? Make sure your GitHub account has been added to a [`getsentry/engineering` team](https://github.com/orgs/getsentry/teams/engineering). If not, open an IT Ticket before continuing.\n\nOtherwise, set the `SENTRY_EXTERNAL_CONTRIBUTOR` environment variable.\n\n## install\n\nDownload [this](https://raw.githubusercontent.com/getsentry/devenv/main/install-devenv.sh) and run it:\n\n```\ncurl https://raw.githubusercontent.com/getsentry/devenv/main/install-devenv.sh \u003e install-devenv.sh\nbash install-devenv.sh\n```\n\nMake sure to call this file `install-devenv.sh` as the script calls itself when you run it.\n\nThis \"global\" devenv is installed to `~/.local/share/sentry-devenv/bin/devenv`.\n\nTo update this installation, run `devenv update`.\n\n\n## user guide\n\n`devenv bootstrap`\n\nThis is intended for initial setup of a new machine.\n\n\n`devenv fetch [repository name]`\n\nAny repository on github in the form of `[org]/[reponame]`\n\nRepositories are cloned to a \"coderoot\" directory which is specified in the [global configuration](#configuration).\n\nNote: `sentry` and `ops` are currently special names which perform more complicated installations (e.g., `sentry` will set up both sentry and getsentry)\n\n`devenv sync`\n\nThis runs a user-supplied `[reporoot]/devenv/sync.py` which should:\n- make sure any desired tools are installed\n- bring the dev environment up-to-date, or create it if it doesn't exist\n\nThis script runs within devenv's [runtime](#runtime), which has access to many useful high-level routines.\nThere are currently no api docs, but referring to the [examples](#examples) should get you 90% of the way there.\n\nIf you have a feature request, please open an issue!\n\nIn general, our library is designed to isolate, as much as possible, a repo's dev environment within `[reporoot]/.devenv`.\nFor example, [gcloud](#gcloud) is installed to `[reporoot]/.devenv/bin/gcloud` (with the gcloud sdk at `[reporoot]/.devenv/bin/google-cloud-sdk`).\nAn exception to this would be python virtualenvs, which was implemented before the idea of `[reporoot]/.devenv`.\n\n\n`devenv doctor`\n\nUse this to diagnose and fix common issues.\n\nRepo-specific checks and fixes can be defined in `[reporoot]/devenv/checks`.\nOtherwise we have \"builtin\" checks and fixes in `devenv.checks`.\n\n\n## technical overview\n\nEverything devenv needs is in `~/.local/share/sentry-devenv`.\n\n- `~/.local/share/sentry-devenv/bin` contains `devenv` and `direnv`\n    - we currently rely on a minimal [`[reporoot]/.envrc`](#direnv) to add `[reporoot]/.devenv/bin` to PATH\n    - see [examples](#examples) for .envrc suggestions\n\n### runtime\n\n- `devenv` is installed exclusively in a virtualenv at `~/.local/share/sentry-devenv/venv`\n    - this venv exclusively uses a python at `~/.local/share/sentry-devenv/python`\n\n\n### global configuration\n\n`~/.config/sentry-devenv/config.ini`\n```ini\n[devenv]\n# the parent directory of all devenv-managed repos\ncoderoot = ~/code\n```\n\n\n### repository configuration\n\n`[reporoot]/devenv/config.ini`\n```ini\n[devenv]\n# optionally require a minimum version to run sync.py\nminimum_version = 1.11.0\n```\n\nThere are plenty more sections, their use is best seen in the [examples](#examples).\n\n\n## examples\n\nSkip to:\n- [direnv](#direnv)\n- [python](#python)\n- [node](#node)\n- [brew](#brew)\n- [colima](#colima)\n- [gcloud](#gcloud)\n- [terraform](#terraform)\n\n### direnv\n\nA minimum viable `[reporoot]/.envrc` is currently needed:\n\n```bash\nif [[ -f \"${PWD}/.env\" ]]; then\n    dotenv\nfi\n\nPATH_add \"${HOME}/.local/share/sentry-devenv/bin\"\n\nif ! command -v devenv \u003e/dev/null; then\n    echo \"install devenv: https://github.com/getsentry/devenv#install\"\n    return 1\nfi\n\nPATH_add \"${PWD}/.devenv/bin\"\n```\n\n### python\n\nNeed a single virtualenv (or have one already at `.venv` you want devenv to manage?)\n\n`[reporoot]/.envrc`\n```bash\nexport VIRTUAL_ENV=\"${PWD}/.venv\"\n\nPATH_add \"${PWD}/.venv/bin\"\n```\n\n`[reporoot]/devenv/sync.py`\n```py\nfrom devenv.lib import config, venv\n\ndef main(context: dict[str, str]) -\u003e int:\n    reporoot = context[\"reporoot\"]\n\n    venv_dir, python_version, requirements, editable_paths, bins = venv.get(reporoot, \"venv\")\n    url, sha256 = config.get_python(reporoot, python_version)\n    print(f\"ensuring venv at {venv_dir}...\")\n    venv.ensure(venv_dir, python_version, url, sha256)\n\n    print(f\"syncing venv with {requirements}...\")\n    venv.sync(reporoot, venv_dir, requirements, editable_paths, bins)\n\n    return 0\n```\n\n`[reporoot]/devenv/config.ini`\n```ini\n[venv.venv]\npython = 3.12.3\npath = .venv\nrequirements = requirements-dev.txt\neditable =\n  .\n\n[python3.12.3]\ndarwin_x86_64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-x86_64-apple-darwin-install_only.tar.gz\ndarwin_x86_64_sha256 = c37a22fca8f57d4471e3708de6d13097668c5f160067f264bb2b18f524c890c8\ndarwin_arm64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-aarch64-apple-darwin-install_only.tar.gz\ndarwin_arm64_sha256 = ccc40e5af329ef2af81350db2a88bbd6c17b56676e82d62048c15d548401519e\nlinux_x86_64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-x86_64-unknown-linux-gnu-install_only.tar.gz\nlinux_x86_64_sha256 = a73ba777b5d55ca89edef709e6b8521e3f3d4289581f174c8699adfb608d09d6\nlinux_arm64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-aarch64-unknown-linux-gnu-install_only.tar.gz\nlinux_arm64_sha256 = ec8126de97945e629cca9aedc80a29c4ae2992c9d69f2655e27ae73906ba187d\n```\n\nYou can also have multiple virtualenvs, which is useful if you rely on a python tool\nthat has a bunch of dependencies that may conflict with others.\n\n`[reporoot]/.envrc`\n```bash\nexport VIRTUAL_ENV=\"${PWD}/.exampleproject\"\n\nPATH_add \"${PWD}/.venv-exampleproject/bin\"\nPATH_add \"${PWD}/.venv-inhouse-tool/bin\"\n```\n\n`[reporoot]/devenv/sync.py`\n```py\nfrom devenv.lib import config, venv\n\ndef main(context: dict[str, str]) -\u003e int:\n    reporoot = context[\"reporoot\"]\n\n    for name in (\"exampleproject\", \"inhouse-tool\"):\n        venv_dir, python_version, requirements, editable_paths, bins = venv.get(reporoot, name)\n        url, sha256 = config.get_python(reporoot, python_version)\n        print(f\"ensuring {name} venv at {venv_dir}...\")\n        venv.ensure(venv_dir, python_version, url, sha256)\n\n        print(f\"syncing {name} with {requirements}...\")\n        venv.sync(reporoot, venv_dir, requirements, editable_paths, bins)\n\n    return 0\n```\n\n`[reporoot]/devenv/config.ini`\n```ini\n[venv.exampleproject]\npython = 3.12.3\nrequirements = requirements-dev.txt\neditable =\n  .\n\n[venv.inhouse-tool]\npython = 3.12.3\nrequirements = inhouse-tool/requirements-dev.txt\n\n[python3.12.3]\ndarwin_x86_64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-x86_64-apple-darwin-install_only.tar.gz\ndarwin_x86_64_sha256 = c37a22fca8f57d4471e3708de6d13097668c5f160067f264bb2b18f524c890c8\ndarwin_arm64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-aarch64-apple-darwin-install_only.tar.gz\ndarwin_arm64_sha256 = ccc40e5af329ef2af81350db2a88bbd6c17b56676e82d62048c15d548401519e\nlinux_x86_64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-x86_64-unknown-linux-gnu-install_only.tar.gz\nlinux_x86_64_sha256 = a73ba777b5d55ca89edef709e6b8521e3f3d4289581f174c8699adfb608d09d6\nlinux_arm64 = https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3+20240415-aarch64-unknown-linux-gnu-install_only.tar.gz\nlinux_arm64_sha256 = ec8126de97945e629cca9aedc80a29c4ae2992c9d69f2655e27ae73906ba187d\n```\n\n### node\n\n`[reporoot]/.envrc`\n```bash\nPATH_add \"${PWD}/node_modules/.bin\"\n```\n\n`[reporoot]/devenv/sync.py`\n```py\nfrom devenv import constants\nfrom devenv.lib import config, node, proc\n\ndef main(context: dict[str, str]) -\u003e int:\n    reporoot = context[\"reporoot\"]\n    cfg = config.get_repo(reporoot)\n\n    node.install(\n        cfg[\"node\"][\"version\"],\n        cfg[\"node\"][constants.SYSTEM_MACHINE],\n        cfg[\"node\"][f\"{constants.SYSTEM_MACHINE}_sha256\"],\n        reporoot,\n    )\n    node.install_yarn(cfg[\"node\"][\"yarn_version\"], reporoot)\n\n    print(\"installing node dependencies...\")\n    proc.run(\n        (\n            \".devenv/bin/yarn\",\n            \"install\",\n            \"--frozen-lockfile\",\n            \"--no-progress\",\n            \"--non-interactive\",\n        ),\n    )\n\n    return 0\n```\n\nIf you'd like a different node version, fill in the appropriate urls https://nodejs.org/dist/\nfirst in config.ini, then reach out to dev-infra and we can mirror it to GCS.\n\n`[reporoot]/devenv/config.ini`\n```ini\n[node]\n# upstream (https://nodejs.org/dist/) is not reliable enough so we've mirrored it to GCS\ndarwin_x86_64 = https://storage.googleapis.com/sentry-dev-infra-assets/node/node-v20.13.1-darwin-x64.tar.xz\ndarwin_x86_64_sha256 = c83bffeb4eb793da6cb61a44c422b399048a73d7a9c5eb735d9c7f5b0e8659b6\ndarwin_arm64 = https://storage.googleapis.com/sentry-dev-infra-assets/node/node-v20.13.1-darwin-arm64.tar.xz\ndarwin_arm64_sha256 = e8a8e78b91485bc95d20f2aa86201485593685c828ee609245ce21c5680d07ce\nlinux_x86_64 = https://storage.googleapis.com/sentry-dev-infra-assets/node/node-v20.13.1-linux-x64.tar.xz\nlinux_x86_64_sha256 = efc0f295dd878e510ab12ea36bbadc3db03c687ab30c07e86c7cdba7eed879a9\n# used for autoupdate\nversion = v20.13.1\nyarn_version = 1.22.22\n```\n\n### brew\n\n`[reporoot]/devenv/sync.py`\n```py\nfrom devenv import constants\nfrom devenv.lib import brew\n\ndef main(context: dict[str, str]) -\u003e int:\n    reporoot = context[\"reporoot\"]\n\n    brew.install()\n\n    proc.run(\n        (f\"{constants.homebrew_bin}/brew\", \"bundle\"),\n        cwd=reporoot,\n    )\n\n    return 0\n```\n\n`[reporoot]/Brewfile`\n```\n# whatever you want, but we generally discourage installing\n# things via brew as it's very difficult to pin a particular\n# version of something\n```\n\n\n### colima\n\nSince devenv 1.14.0, colima (and the docker CLI needed to interact with it)\nshould have been installed globally for you during bootstrap.\nIf you're on an older version, run `devenv update`.\n\n\n### gcloud\n\n`[reporoot]/devenv/sync.py`\n```py\nfrom devenv import constants\nfrom devenv.lib import config, gcloud\n\ndef main(context: dict[str, str]) -\u003e int:\n    reporoot = context[\"reporoot\"]\n    cfg = config.get_repo(reporoot)\n\n    gcloud.install(\n        cfg[\"gcloud\"][\"version\"],\n        cfg[\"gcloud\"][SYSTEM_MACHINE],\n        cfg[\"gcloud\"][f\"{SYSTEM_MACHINE}_sha256\"],\n        reporoot,\n    )\n\n    return 0\n```\n\n`[reporoot]/devenv/config.ini`\n```ini\n[gcloud]\n# custom python version not supported yet, it just uses\n# devenv's internal python 3.11\ndarwin_x86_64 = https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-490.0.0-darwin-x86_64.tar.gz\ndarwin_x86_64_sha256 = fa396909acc763cf831dd5d89e778999debf37ceadccb3c1bdec606e59ba2694\ndarwin_arm64 = https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-490.0.0-darwin-arm.tar.gz\ndarwin_arm64_sha256 = a3a098a5f067b561e003c37284a9b164f28f37fd0d6371bb55e326679f48641c\nlinux_x86_64 = https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-490.0.0-linux-x86_64.tar.gz\nlinux_x86_64_sha256 = 40ce41958236f76d9cb08f377ccb9fd6502d2df4da14b36d9214bcb620e2b020\n# used for autoupdate\nversion = 490.0.0\n```\n\n\n### terraform\n\nOur responsibility ends at installing `tenv` and containing `TENV_ROOT` at  `[reporoot]/.devenv/bin/tenv-root`. We install `terraform` and `terragrunt` shims which use that `TENV_ROOT`.\n\nDefine `[reporoot]/.terraform-version` and `[reporoot]/.terragrunt-version` (if you want it) and after running sync, you should be able to just type `terraform` and `tenv` takes care of the rest.\n\n\n`[reporoot]/devenv/sync.py`\n```py\nfrom devenv import constants\nfrom devenv.lib import config, tenv\n\ndef main(context: dict[str, str]) -\u003e int:\n    reporoot = context[\"reporoot\"]\n    cfg = config.get_repo(reporoot)\n\n    tenv.install(\n        cfg[\"tenv\"][\"version\"],\n        cfg[\"tenv\"][SYSTEM_MACHINE],\n        cfg[\"tenv\"][f\"{SYSTEM_MACHINE}_sha256\"],\n        reporoot,\n    )\n\n    return 0\n```\n\n`[reporoot]/devenv/config.ini`\n```ini\n[tenv]\ndarwin_x86_64 = https://github.com/tofuutils/tenv/releases/download/v1.3.0/tenv_v1.3.0_Darwin_x86_64.tar.gz\ndarwin_x86_64_sha256 = 994100d26f4de6de4eebc7691ca4ea7b424e2fd73e6d5d77c5bf6dfd4af94752\ndarwin_arm64 =  https://github.com/tofuutils/tenv/releases/download/v1.3.0/tenv_v1.3.0_Darwin_arm64.tar.gz\ndarwin_arm64_sha256 = c31d2b8412147316a0cadb684408bc123e567852d7948091be7e4303fc19397a\n# used for autoupdate\nversion = v1.3.0\n```\n\n\n## develop\n\nWe use `tox`. The easiest way to run devenv locally is just using the tox venv's executable:\n\n```\n~/code/sentry $  ~/code/devenv/.tox/py311/bin/devenv sync\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetsentry%2Fdevenv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetsentry%2Fdevenv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetsentry%2Fdevenv/lists"}