Skip to content

Commit 1bf7961

Browse files
committed
Add e2e mini apps with devcontainer setup
1 parent a62b534 commit 1bf7961

15 files changed

Lines changed: 1907 additions & 34 deletions

File tree

.devcontainer/.env.example

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1-
IMAGE=bitnami/ruby
1+
# Official Ruby images
2+
IMAGE=ruby
23

34
# Adjust as needed
4-
TAG=3.4
5+
VERSION=3.4.5
56

67
# IMAGE=jruby
78
# TAG=latest
9+
10+
# E2E testing
11+
SENTRY_DSN="http://user:pass@sentry.localhost/project/42"
12+
SENTRY_DSN_JS="http://user:pass@sentry-js.localhost/project/43"
13+
14+
SENTRY_E2E_RAILS_APP_PORT=4000
15+
SENTRY_E2E_SVELTE_APP_PORT=4001
16+
17+
SENTRY_E2E_RAILS_APP_URL="http://sentry-test-services:4000"
18+
SENTRY_E2E_SVELTE_APP_URL="http://sentry-test-services:4001"
19+
20+
# Faster builds with compose
21+
COMPOSE_BAKE=true

.devcontainer/Dockerfile

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
ARG IMAGE="bitnami/ruby"
2-
ARG TAG="latest"
1+
ARG IMAGE="ruby"
2+
ARG VERSION="3.4.5"
3+
ARG DISTRO="slim-bookworm"
34

4-
FROM ${IMAGE}:${TAG}
5+
FROM ${IMAGE}:${VERSION}-${DISTRO} AS build
56

6-
USER root
7-
RUN apt-get update && apt-get install -y \
7+
RUN apt-get update && apt-get install -y --no-install-recommends \
8+
sudo \
89
gnupg \
910
git \
1011
curl \
1112
wget \
12-
zsh \
13-
vim \
1413
build-essential \
15-
sudo \
14+
pkg-config \
1615
libssl-dev \
1716
libreadline-dev \
1817
zlib1g-dev \
@@ -22,31 +21,56 @@ RUN apt-get update && apt-get install -y \
2221
libncurses5-dev \
2322
libffi-dev \
2423
libgdbm-dev \
24+
sqlite3 \
25+
nodejs \
26+
npm \
27+
chromium \
28+
chromium-driver \
2529
&& apt-get clean \
2630
&& rm -rf /var/lib/apt/lists/*
2731

28-
RUN groupadd --gid 1000 sentry \
29-
&& useradd --uid 1000 --gid sentry --shell /bin/zsh --create-home sentry
30-
31-
# Add sentry to sudoers with NOPASSWD option
3232
RUN echo "sentry ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/sentry \
3333
&& chmod 0440 /etc/sudoers.d/sentry
3434

35+
RUN groupadd --gid 1000 sentry \
36+
&& useradd --uid 1000 --gid sentry --shell /bin/bash --create-home sentry
37+
3538
WORKDIR /workspace/sentry
3639

3740
RUN chown -R sentry:sentry /workspace/sentry
38-
RUN mkdir /workspace/gems && chown -R sentry:sentry /workspace/gems
3941

40-
ARG TAG=latest
41-
ARG GEM_HOME="/workspace/gems/${TAG}"
42+
ARG VERSION
43+
ARG GEM_HOME="/workspace/gems/${VERSION}"
44+
45+
RUN mkdir /workspace/gems && chown -R sentry:sentry /workspace/gems
4246

4347
ENV LANG=C.UTF-8 \
4448
BUNDLE_JOBS=4 \
4549
BUNDLE_RETRY=3 \
46-
GEM_HOME=/workspace/gems/${TAG} \
50+
GEM_HOME=/workspace/gems/${VERSION} \
4751
PATH=$PATH:${GEM_HOME}/bin \
4852
REDIS_HOST=redis
4953

54+
FROM build AS dev
55+
5056
USER sentry
5157

52-
CMD ["ruby", "--version"]
58+
COPY .devcontainer/entrypoint.sh /workspace/entrypoint.sh
59+
60+
ENTRYPOINT ["/workspace/entrypoint.sh"]
61+
62+
FROM build AS test
63+
64+
COPY . .
65+
66+
RUN chown -R sentry:sentry .
67+
68+
USER sentry
69+
70+
RUN gem install foreman && \
71+
bundle install && \
72+
cd spec/apps/rails-mini && \
73+
bundle install
74+
75+
RUN cd spec/apps/svelte-mini && \
76+
npm install

.devcontainer/devcontainer.json

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
{
22
"name": "sentry-ruby",
33
"dockerComposeFile": "docker-compose.yml",
4-
"service": "app",
4+
"service": "sentry-dev",
55
"workspaceFolder": "/workspace/sentry",
6+
"features": {
7+
"ghcr.io/devcontainers/features/github-cli": {},
8+
"ghcr.io/nils-geistmann/devcontainers-features/zsh": {},
9+
"ghcr.io/devcontainers-extra/features/npm-packages": {},
10+
"ghcr.io/rocker-org/devcontainer-features/apt-packages": {
11+
"packages": "inotify-tools"
12+
}
13+
},
614
"customizations": {
715
"vscode": {
816
"extensions": [
917
"sleistner.vscode-fileutils",
1018
"Shopify.ruby-lsp"
1119
],
12-
"settings": {}
13-
},
14-
"rubyLsp.rubyVersionManager": {
15-
"identifier": "none"
20+
"editor.formatOnSaveMode": "modifications",
21+
"editor.formatOnSave": true,
22+
"rubyLsp.rubyVersionManager": {
23+
"identifier": "auto"
24+
},
25+
"rubyLsp.formatter": "auto"
1626
}
1727
},
18-
"remoteUser": "sentry",
19-
"postCreateCommand": "ruby --version"
28+
"remoteUser": "sentry"
2029
}

.devcontainer/docker-compose.yml

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,51 @@
11
services:
2-
app:
2+
sentry-build: &sentry-build
33
build:
4-
context: .
5-
dockerfile: Dockerfile
4+
context: ..
5+
dockerfile: .devcontainer/Dockerfile
6+
target: test
67
args:
78
IMAGE: ${IMAGE}
8-
TAG: ${TAG}
9+
VERSION: ${VERSION}
10+
SENTRY_E2E_RAILS_APP_PORT: ${SENTRY_E2E_RAILS_APP_PORT}
11+
SENTRY_E2E_SVELTE_APP_PORT: ${SENTRY_E2E_SVELTE_APP_PORT}
12+
SENTRY_E2E_RAILS_APP_URL: ${SENTRY_E2E_RAILS_APP_URL}
13+
SENTRY_E2E_SVELTE_APP_URL: ${SENTRY_E2E_SVELTE_APP_URL}
914
volumes:
1015
- ..:/workspace/sentry:cached
11-
command: sleep infinity
16+
- sentry_e2e_logs:/workspace/sentry/log
17+
working_dir: /workspace/sentry
1218
environment:
1319
- REDIS_URL=${REDIS_URL:-redis://redis:6379/0}
20+
env_file: [".env"]
21+
22+
sentry-dev:
23+
<<: *sentry-build
24+
command: sleep infinity
1425
depends_on:
1526
- redis
1627

28+
sentry-test:
29+
<<: *sentry-build
30+
depends_on:
31+
- redis
32+
- sentry-test-services
33+
34+
sentry-test-services:
35+
<<: *sentry-build
36+
command: "foreman start"
37+
ports:
38+
- ${SENTRY_E2E_RAILS_APP_PORT}
39+
- ${SENTRY_E2E_SVELTE_APP_PORT}
40+
1741
redis:
1842
image: redis:latest
1943
environment:
2044
- ALLOW_EMPTY_PASSWORD=yes
2145
ports:
2246
- "6379:6379"
47+
48+
volumes:
49+
sentry_e2e_logs:
50+
sentry_ruby_gems:
51+
sentry_node_modules:

.devcontainer/setup

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#!/usr/bin/env ruby
2+
3+
# frozen_string_literal: true
4+
5+
require 'optparse'
6+
require 'fileutils'
7+
8+
class SetupScript
9+
WORKSPACE_FOLDERS = %w[
10+
sentry-ruby
11+
sentry-rails
12+
sentry-sidekiq
13+
sentry-delayed_job
14+
sentry-resque
15+
sentry-opentelemetry
16+
].freeze
17+
18+
def initialize
19+
@options = {
20+
only_folders: [],
21+
only_bundle: false,
22+
only_npm: false,
23+
with_foreman: false
24+
}
25+
@workspace_root = '/workspace/sentry'
26+
end
27+
28+
def run(args)
29+
parse_options(args)
30+
31+
puts "🚀 Running post-create setup script..."
32+
33+
Dir.chdir(@workspace_root)
34+
35+
if should_run_bundle?
36+
cleanup_ruby_lsp_directories
37+
install_bundle_dependencies
38+
install_foreman_gem if @options[:with_foreman]
39+
end
40+
41+
if should_run_npm?
42+
install_npm_dependencies
43+
end
44+
45+
puts "✅ Post-create setup completed!"
46+
end
47+
48+
private
49+
50+
def parse_options(args)
51+
parser = OptionParser.new do |opts|
52+
opts.banner = "Usage: setup.rb [options]"
53+
54+
opts.on("--only FOLDERS", Array, "Only process specified folders (comma-separated)") do |folders|
55+
@options[:only_folders] = folders
56+
end
57+
58+
opts.on("--only-bundle", "Only run bundle operations (skip npm)") do
59+
@options[:only_bundle] = true
60+
end
61+
62+
opts.on("--only-npm", "Only run npm operations (skip bundle)") do
63+
@options[:only_npm] = true
64+
end
65+
66+
opts.on("--with-foreman", "Install foreman gem (default: false)") do
67+
@options[:with_foreman] = true
68+
end
69+
70+
opts.on("-h", "--help", "Show this help message") do
71+
puts opts
72+
exit
73+
end
74+
end
75+
76+
parser.parse!(args)
77+
78+
if @options[:only_bundle] && @options[:only_npm]
79+
puts "❌ Error: --only-bundle and --only-npm are mutually exclusive"
80+
exit 1
81+
end
82+
end
83+
84+
def should_run_bundle?
85+
!@options[:only_npm]
86+
end
87+
88+
def should_run_npm?
89+
!@options[:only_bundle]
90+
end
91+
92+
def target_folders
93+
return @options[:only_folders] unless @options[:only_folders].empty?
94+
WORKSPACE_FOLDERS
95+
end
96+
97+
def all_folders
98+
['.'] + target_folders
99+
end
100+
101+
def cleanup_ruby_lsp_directories
102+
puts "🧹 Cleaning up .ruby-lsp directories..."
103+
104+
all_folders.each do |folder|
105+
ruby_lsp_path = File.join(folder, '.ruby-lsp')
106+
if Dir.exist?(ruby_lsp_path)
107+
puts " Removing #{folder}/.ruby-lsp"
108+
FileUtils.rm_rf(ruby_lsp_path)
109+
end
110+
end
111+
end
112+
113+
def install_bundle_dependencies
114+
puts "📦 Installing bundle dependencies for workspace folders..."
115+
116+
target_folders.each do |folder|
117+
folder_path = File.join(@workspace_root, folder)
118+
gemfile_path = File.join(folder_path, 'Gemfile')
119+
120+
if Dir.exist?(folder_path) && File.exist?(gemfile_path)
121+
Dir.chdir(folder_path) do
122+
run_with_spinner(" #{folder}") do
123+
system('bundle install > /dev/null 2>&1')
124+
end
125+
end
126+
127+
Dir.chdir(@workspace_root)
128+
else
129+
puts " Skipping #{folder} (no Gemfile found or directory doesn't exist)"
130+
end
131+
end
132+
end
133+
134+
def install_foreman_gem
135+
run_with_spinner("💎 Installing foreman gem") do
136+
system('gem install foreman > /dev/null 2>&1')
137+
end
138+
end
139+
140+
def install_npm_dependencies
141+
svelte_mini_path = File.join(@workspace_root, 'spec/apps/svelte-mini')
142+
143+
if Dir.exist?(svelte_mini_path)
144+
Dir.chdir(svelte_mini_path) do
145+
run_with_spinner("📦 Installing npm dependencies for e2e tests") do
146+
system('npm install > /dev/null 2>&1')
147+
end
148+
end
149+
else
150+
puts "❌ Svelte mini app directory not found: #{svelte_mini_path}"
151+
exit 1
152+
end
153+
end
154+
155+
def run_with_spinner(message)
156+
print "#{message} "
157+
158+
spinner_chars = %w[- \\ | /]
159+
spinner_index = 0
160+
spinner_running = true
161+
162+
spinner_thread = Thread.new do
163+
while spinner_running
164+
print "\r#{message} #{spinner_chars[spinner_index]}"
165+
spinner_index = (spinner_index + 1) % spinner_chars.length
166+
sleep 0.1
167+
end
168+
end
169+
170+
# Run the actual command
171+
success = yield
172+
173+
# Stop spinner
174+
spinner_running = false
175+
spinner_thread.join
176+
177+
if success
178+
puts "\r#{message} ✅"
179+
else
180+
puts "\r#{message} ❌"
181+
puts "❌ Command failed. Please check for missing dependencies or run manually."
182+
exit 1
183+
end
184+
end
185+
end
186+
187+
if __FILE__ == $0
188+
SetupScript.new.run(ARGV)
189+
end

0 commit comments

Comments
 (0)