Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 3 additions & 19 deletions .agents/skills/setup-dev/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,24 +153,9 @@ This is the longest step. Tell the user:

> **This will take 10-20 minutes** on first run. It installs Python, Node, all pip/npm dependencies, and runs database migrations. Subsequent syncs are much faster (2-5 min).

### If direnv hangs
### Before the first sync

The `.envrc` runs Docker checks. If the Docker runtime isn't running, direnv will hang. Symptoms:

```
direnv: ([...]/direnv export zsh) is taking a while to execute. Use CTRL-C to give up.
```

**Fix**: Start the Docker runtime first:

- OrbStack: Open OrbStack.app or `open -a OrbStack`
- Colima: `devenv colima start`

Then `direnv allow` again.

### Chicken-and-Egg Problem

direnv checks node version and sentry installation. On a fresh setup, these don't exist yet, so direnv will fail. This is normal. **Bypass direnv and run devenv sync directly:**
`.envrc` only sets environment variables and PATH. On a fresh checkout it still loads and prints a `Run: devenv sync` hint. Run sync directly:

```bash
~/.local/share/sentry-devenv/bin/devenv sync
Expand All @@ -182,7 +167,7 @@ Or if devenv is on PATH:
devenv sync
```

After sync completes, `direnv allow` should succeed.
After sync completes, `direnv allow` activates the environment.

### If devenv sync fails

Expand Down Expand Up @@ -314,7 +299,6 @@ Each worktree has its own `.venv`. When you create a worktree with `git worktree

| Symptom | Likely Cause | Fix |
| ----------------------------------------------- | ----------------------------------------- | ---------------------------------------------------- |
| direnv hangs | Docker runtime not running | Start OrbStack / Colima |
| `devenv sync` fails with version error | Outdated devenv | `devenv update` or reinstall |
| `devservices up` says "colima not running" | Using OrbStack, script only checks Colima | Patch `devservices.py` — see Step 6 |
| Server 500s on every page | DB not seeded | `.venv/bin/sentry upgrade --noinput` |
Expand Down
233 changes: 20 additions & 213 deletions .envrc
Original file line number Diff line number Diff line change
@@ -1,95 +1,10 @@
#!/not/executable/bash
# This is the .envrc for sentry, for use with direnv.
# It's responsible for enforcing a standard dev environment by checking as much state as possible, and either performing
# initialization (e.g. activating the venv) or giving recommendations on how to reach the desired state.
# It also sets useful environment variables.
# If you'd like to override or set any custom environment variables, this .envrc will read a .env file at the end.
# direnv activation for sentry: environment variables and PATH, nothing else.
# `devenv sync` installs and repairs the environment; `devenv doctor` diagnoses it.
# Put local overrides in a .env file.
set -eu

# Upgrading Mac can uninstall the Command Line Tools, thus, removing our access to git
# The message talks about xcrun, however, we can use the lack of git as a way to know that we need this
# xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools),
# missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
if [ "$(uname -s)" == "Darwin" ] && [ ! -f "/Library/Developer/CommandLineTools/usr/bin/git" ]; then
echo -e "$(tput setaf 1)\nERROR: Complete the interactive installation (10+ mins) of the Command Line Tools.$(tput sgr0)"
xcode-select --install
return 1
fi

source "scripts/lib.sh"

bold="$(tput bold)"
red="$(tput setaf 1)"
green="$(tput setaf 2)"
yellow="$(tput setaf 3)"
reset="$(tput sgr0)"

# XXX: we can't trap bash EXIT, because it'll override direnv's finalizing routines.
# consequently, using "exit" anywhere will skip this notice from showing.
# so need to use set -e, and return 1.
trap notice ERR

complete_success="yup"



help_message() {
cat <<EOF
For more help run: make direnv-help
EOF
}

failure_message() {
cat <<EOF
${red}${bold}direnv wasn't able to complete execution.
You may have been given some recommendations in the error message.
Follow them, and then you'll need to re-run direnv by running "direnv allow".${reset}
EOF
help_message
}

notice() {
[ $? -eq 0 ] && return
failure_message
}

debug() {
if [ "${SENTRY_DIRENV_DEBUG-}" ]; then
echo -e "${@}"
fi
}

info() {
echo -e "${bold}${*}${reset}"
}

warn() {
echo -e "${yellow}${*}${reset}" >&2
complete_success="nope"
}

die() {
echo -e "${red}${bold}FATAL: ${*}${reset}" >&2
return 1
}

show_commands_info() {
echo -e "\n${red}Run the following commands to bring your environment up-to-date:"
for cmd in "${commands_to_run[@]}"; do
warn " ${red}$cmd"
done
echo ""
}

### Environment ###

commands_to_run=()

# Always write stdout immediately. Very helpful for debugging
export PYTHONUNBUFFERED=1

# make sure we don't have any conflicting PYTHONPATH
unset PYTHONPATH

# increase node's memory limit, required for our webpacking
Expand All @@ -99,140 +14,32 @@ export NODE_OPTIONS="--max-old-space-size=5120"
# Enable this by default for development envs (CI/deploys do not use envrc)
export SENTRY_UI_HOT_RELOAD=1

### You can override the exported variables with a .env file
# All exports should happen before here unless they're safeguarded (see devenv error reporting below)
if [ -f ".env" ]; then
info "Loading variables from .env"
dotenv
fi
# Watches .env even while it's absent, so creating it triggers a reload.
dotenv_if_exists

## Notify of reporting to Sentry
if [ -n "${SENTRY_DEVENV_NO_REPORT+x}" ]; then
debug "No development environment errors will be reported (since you've defined SENTRY_DEVENV_NO_REPORT)."
_SENTRY_LOG_FILE=''
else
# Since direnv traps the EXIT signal we place the temp file under /tmp for the odd time
# the script will use the EXIT path
_SENTRY_LOG_FILE=$(mktemp /tmp/sentry.envrc.out.$$.XXXXXX)
exec > >(tee "$_SENTRY_LOG_FILE")
exec 2>&1
debug "Development errors will be reported to Sentry.io. If you wish to opt-out, set SENTRY_DEVENV_NO_REPORT as an env variable."
# Development environment errors are reported to Sentry.io. Set SENTRY_DEVENV_NO_REPORT to opt out.
if [ -z "${SENTRY_DEVENV_NO_REPORT+x}" ]; then
export SENTRY_DEVSERVICES_DSN=https://23670f54c6254bfd9b7de106637808e9@o1.ingest.sentry.io/1492057
fi

# for deduplicating
PATH_rm "/opt/homebrew/bin"

# homebrew must not be searched first, we need venv and devenv to take precedence
PATH_add "/opt/homebrew/bin"

# PATH_add prepends, so entries listed earlier rank lower. npm ships a binary
# named `sentry`, which must not shadow the venv's.
# PATH_add prepends, so later entries take precedence. Homebrew is moved ahead
# of the system paths, but the checkout's tools must win over it.
PATH_rm /opt/homebrew/bin
PATH_add /opt/homebrew/bin
PATH_add /opt/homebrew/share/google-cloud-sdk/bin
# npm ships a binary named `sentry`, which must not shadow the venv's.
PATH_add node_modules/.bin

### Python ###
PATH_add .devenv/bin

export VIRTUAL_ENV="${PWD}/.venv"
PATH_add "${VIRTUAL_ENV}/bin"

if [ -f "${VIRTUAL_ENV}/bin/devenv" ]; then
DEVENV="${VIRTUAL_ENV}/bin/devenv"
else
DEVENV=devenv
fi

export SENTRY_DEVENV_HOME="${SENTRY_DEVENV_HOME:-$XDG_DATA_HOME/sentry-devenv}"
# The global devenv, not the copy pinned in the venv.
export SENTRY_DEVENV_HOME="${SENTRY_DEVENV_HOME:-${XDG_DATA_HOME:-$HOME/.local/share}/sentry-devenv}"
PATH_add "${SENTRY_DEVENV_HOME}/bin"
if ! command -v "$DEVENV" >/dev/null; then
die '
Please install the devenv tool:
https://github.com/getsentry/devenv#install
'
fi

if ! [ -x "${VIRTUAL_ENV}/bin/sentry" ]; then
warn "Your virtualenv is activated, but sentry doesn't seem to be installed."
commands_to_run+=("devenv sync")
fi

# this is the standard repo-local bin root
PATH_add "${PWD}/.devenv/bin"

# gcloud and friends
PATH_add "/opt/homebrew/share/google-cloud-sdk/bin"

# pnpm prepends node_modules/.bin to PATH, even when the venv comes first here.
rm -f node_modules/.bin/sentry
hash -r

# Only remove shadowing executables once the expected command is installed.
if [ -x "${VIRTUAL_ENV}/bin/sentry" ]; then
while [ "$(command -v sentry)" != "${VIRTUAL_ENV}/bin/sentry" ]; do
sentry_path="$(command -v sentry || true)"
if [ "$(type -t sentry)" != "file" ] || [ ! -f "$sentry_path" ] || [ "$sentry_path" -ef "${VIRTUAL_ENV}/bin/sentry" ]; then
die "Expected sentry to resolve to ${VIRTUAL_ENV}/bin/sentry, got: ${sentry_path:-not found}"
fi
# Resolve parent directories, not the executable: unlinking a local shim
# is safe, but following a directory symlink could delete a global tool.
sentry_dir="$(cd -- "$(dirname -- "$sentry_path")" && pwd -P)"
case "$sentry_dir/" in
"$(pwd -P)/"*) ;;
*) die "Refusing to remove $sentry_path outside this checkout. Adjust PATH so ${VIRTUAL_ENV}/bin/sentry takes precedence." ;;
esac
info "Removing $sentry_path: it shadows ${VIRTUAL_ENV}/bin/sentry"
rm -f -- "$sentry_path"
hash -r
done
if ! has devenv; then
log_error "devenv isn't installed. See https://github.com/getsentry/devenv#install"
elif [ ! -x "${VIRTUAL_ENV}/bin/sentry" ]; then
log_error "sentry isn't installed in ${VIRTUAL_ENV}. Run: devenv sync"
fi

### prek ###

debug "Checking prek..."

if ! require prek; then
warn "Looks like you don't have prek installed."
commands_to_run+=("devenv sync")
fi

### dotagents ###

if [ -f "agents.toml" ] && { [ ! -s "agents.lock" ] || [ ! -d ".agents/skills" ] || [ -z "$(ls -A ".agents/skills" 2>/dev/null)" ]; }; then
warn "Agent skills not installed."
commands_to_run+=("devenv sync")
fi

### Node ###

if [ -f ".node-version" ]; then
debug "Checking node..."

if [ "${SENTRY_DEVENV_SKIP_FRONTEND:-}" != "1" ]; then
if ! require node; then
die "You don't seem to have node installed. Please run devenv sync."
fi

read -r node_version < ".node-version"
if [ "v${node_version}" != "$(node --version)" ]; then
die "Unexpected $(command -v node) version. Please run devenv sync."
fi

if [ ! -d "node_modules" ]; then
die "You don't seem to have pnpm packages installed. Please run devenv sync."
fi
fi
fi

# These are commands that can take a significant amount of time
if [ ${#commands_to_run[@]} -ne 0 ]; then
show_commands_info
fi

if [ "${complete_success}" != "yup" ]; then
help_message
warn "\nPartial success. The virtualenv is active, however, you're not fully up-to-date (see messages above)."
else
echo "${green}${bold}SUCCESS!${reset}"
fi

# Since we can't use an EXIT routine we need to guarantee we delete the file here
[ -z "$_SENTRY_LOG_FILE" ] || rm -f "$_SENTRY_LOG_FILE"
9 changes: 9 additions & 0 deletions .github/workflows/development-environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
- '.python-version'
- '.envrc'
- 'Brewfile'
- 'devenv/**'
- 'scripts/**'
- 'tools/**'
- 'src/sentry/runner/commands/devserver.py'
Expand Down Expand Up @@ -77,3 +78,11 @@ jobs:
- name: devenv sync
run: |
devenv --nocoderoot sync

- name: direnv activation
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq direnv
direnv allow
direnv exec . bash -euc 'test "$(command -v sentry)" = "$PWD/.venv/bin/sentry"' 2>&1 | tee direnv.log
if grep -q "isn't installed" direnv.log; then exit 1; fi
2 changes: 2 additions & 0 deletions .github/workflows/migrations-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ on:
paths:
- 'src/sentry/**/migrations/**.py'
- 'tools/migrations/drop_pending_deletions.py'
- 'tools/dev_db.py'
- 'Makefile'
- '.github/workflows/migrations-drift.yml'

# Cancel in progress workflows on pull_requests.
Expand Down
44 changes: 35 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,41 @@ bootstrap:
@echo "you probably want to run devenv sync to bring the"
@echo "sentry dev environment up to date!"

build-platform-assets \
clean \
init-config \
run-dependent-services \
drop-db \
create-db \
apply-migrations \
reset-db :
@./scripts/do.sh $@
.PHONY: init-config run-dependent-services build-platform-assets clean create-db drop-db apply-migrations reset-db
init-config:
sentry init --dev --no-clobber

run-dependent-services:
devservices up

build-platform-assets:
@echo "--> Building platform assets"
python3 -m sentry.build._integration_docs
@# make sure this didn't silently do nothing
@test -f src/sentry/integration-docs/android.json

clean:
@echo "--> Cleaning static cache"
rm -rf dist/* src/sentry/static/sentry/dist/*
@echo "--> Cleaning integration docs cache"
rm -rf src/sentry/integration-docs
@echo "--> Cleaning pyc files"
find . -name "*.pyc" -delete
@echo "--> Cleaning python build artifacts"
rm -rf build/ dist/ src/sentry/assets.json

create-db:
@python3 -m tools.dev_db create

drop-db:
@python3 -m tools.dev_db drop

apply-migrations:
@python3 -m tools.dev_db migrate

# One invocation keeps drop, migrate and createuser ordered under `make -j`.
reset-db:
@python3 -m tools.dev_db reset

develop \
install-js-dev \
Expand Down
Loading
Loading