Skip to content

Commit 96d7707

Browse files
authored
Merge pull request #369 from appsignal/environment-switching-param
Switch environments with an `env=<name>` parameter
2 parents 5ed2627 + bb65d76 commit 96d7707

7 files changed

Lines changed: 145 additions & 16 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
nodejs/opentelemetry-instrumentation-bullmq
55
.DS_Store
66
appsignal_key.env
7+
appsignal_key.*.env
78
.env
89
yarn-error.log
910
node_modules

README.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,32 @@ Next, checkout the integrations locally:
1313
rake integrations:clone
1414
```
1515

16-
Generate an environment file using a valid push api key you
17-
can get on [AppSignal](https://appsignal.com):
16+
Pick the environment to send data to. The `local` and `staging` environments
17+
work out of the box:
1818

1919
```
20-
rake global:set_push_api_key key=<key>
20+
rake env:local
21+
rake env:staging
22+
```
23+
24+
Switching writes an `appsignal_key.<name>.env` file (seeded from a committed
25+
`appsignal_key.<name>.env.example` default when there is one) and copies it into
26+
`appsignal_key.env`, the file every test setup reads, tagging it with an
27+
`# ENV: <name>` marker. The active environment's contents are printed on boot,
28+
so you can always see which one is in use.
29+
30+
Pass a push api key (you can get one on [AppSignal](https://appsignal.com)) to
31+
set it for that environment while switching; it's remembered on later switches:
32+
33+
```
34+
rake env:prod key=<key>
35+
```
36+
37+
`env:local`, `env:staging` and `env:prod` are shortcuts for the general form,
38+
which works for any environment name:
39+
40+
```
41+
rake env=<name> key=<key> env:switch
2142
```
2243

2344
To start a test setup:

Rakefile

Lines changed: 91 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,76 @@ require 'fileutils'
44
LANGUAGES = %w(elixir go java javascript nodejs php python ruby standalone vector)
55
PROCESSMON_PATH = "support/processmon/processmon"
66

7+
# The active environment file every test setup reads. It's written by
8+
# `env:switch` from a per-environment `appsignal_key.<name>.env` file, with an
9+
# `# ENV: <name>` marker line prepended so the active environment is visible in
10+
# the file itself (it's also printed on boot).
11+
ACTIVE_KEY_FILE = "appsignal_key.env"
12+
713
def get_app
814
ENV['app'].tap do |app|
915
raise "Specify which app you want to run using app=path" if app.nil?
1016
raise "#{app} not found" unless File.exist?(app)
1117
end.delete_suffix("/")
1218
end
1319

20+
# The environment name from the `env=` parameter, e.g. `prod` for
21+
# `appsignal_key.prod.env`.
22+
def get_env
23+
ENV['env'].tap do |name|
24+
raise "Specify which environment you want using env=<name>" if name.nil? || name.strip.empty?
25+
end.strip
26+
end
27+
28+
# The per-environment key file that `env=<name>` selects.
29+
def env_key_file(name)
30+
"appsignal_key.#{name}.env"
31+
end
32+
33+
# A committed default for an environment, copied into the per-environment file
34+
# the first time you switch to it. `local` and `staging` ship one; other
35+
# environments start from whatever key you pass.
36+
def default_env_file(name)
37+
"#{env_key_file(name)}.example"
38+
end
39+
40+
# Set the push api key in a key file, replacing an existing
41+
# `APPSIGNAL_PUSH_API_KEY` line if present and leaving the rest of the file
42+
# (endpoints and so on) untouched. Creates the file if it doesn't exist.
43+
def set_push_api_key(file, key)
44+
var = "APPSIGNAL_PUSH_API_KEY"
45+
lines = File.exist?(file) ? File.readlines(file, :chomp => true) : []
46+
replaced = false
47+
lines.map! do |line|
48+
next line unless line.start_with?("#{var}=")
49+
replaced = true
50+
"#{var}=#{key}"
51+
end
52+
lines << "#{var}=#{key}" unless replaced
53+
File.write file, lines.join("\n") + "\n"
54+
end
55+
56+
# Make `name` the active environment: seed its key file from the committed
57+
# default if needed, set the key when one is given, then copy it into
58+
# `appsignal_key.env` with an `# ENV: <name>` marker.
59+
def switch_env(name, key = nil)
60+
source = env_key_file(name)
61+
62+
if !File.exist?(source) && File.exist?(default_env_file(name))
63+
puts "Creating #{source} from #{default_env_file(name)}"
64+
FileUtils.cp default_env_file(name), source
65+
end
66+
67+
set_push_api_key(source, key) if key
68+
69+
unless File.exist?(source)
70+
raise "No #{source} found. Provide a key to create it, e.g. rake env=#{name} key=<key> env:switch"
71+
end
72+
73+
File.write ACTIVE_KEY_FILE, "# ENV: #{name}\n#{File.read(source)}"
74+
puts "Switched active environment to '#{name}'."
75+
end
76+
1477
# A mode is just a `docker-compose.<mode>.yml` file in the app directory. The
1578
# `shared` file is reserved (it holds the common services every mode includes)
1679
# and is never a selectable mode. Returns a `{ mode_name => filename }` map.
@@ -167,6 +230,28 @@ def render_erb(file)
167230
ERB.new(File.read(file)).result
168231
end
169232

233+
namespace :env do
234+
desc "Switch the active environment, e.g. rake env=prod env:switch (pass key=<key> to also set its key)"
235+
task :switch do
236+
switch_env(get_env, ENV['key'])
237+
end
238+
239+
desc "Switch to the local environment (pass key=<key> to also set its key)"
240+
task :local do
241+
switch_env("local", ENV['key'])
242+
end
243+
244+
desc "Switch to the staging environment (pass key=<key> to also set its key)"
245+
task :staging do
246+
switch_env("staging", ENV['key'])
247+
end
248+
249+
desc "Switch to the production environment (pass key=<key> to also set its key)"
250+
task :prod do
251+
switch_env("prod", ENV['key'])
252+
end
253+
end
254+
170255
namespace :app do
171256
desc "Open the browser pointing to the app"
172257
task :open do
@@ -203,8 +288,8 @@ namespace :app do
203288
end
204289

205290
def build_app
206-
unless File.exist?("appsignal_key.env")
207-
raise "No push api key set yet, run rake global:set_push_api_key key=<key>"
291+
unless File.exist?(ACTIVE_KEY_FILE)
292+
raise "No active environment set yet, run e.g. rake env:local or rake env=<name> key=<key> env:switch"
208293
end
209294
unless File.exist?(PROCESSMON_PATH)
210295
puts "Processmon not present. Building processmon..."
@@ -215,6 +300,10 @@ namespace :app do
215300
@mode = get_mode(@app)
216301
puts "Starting #{@app}"
217302

303+
puts "=" * 50
304+
puts File.read(ACTIVE_KEY_FILE)
305+
puts "=" * 50
306+
218307
puts "Copying processmon"
219308
FileUtils.rm_f "#{@app}/commands/processmon"
220309
FileUtils.cp "support/processmon/processmon", "#{@app}/commands/"
@@ -433,13 +522,6 @@ namespace :global do
433522
File.write "README.md", render_erb("support/templates/README.md.erb")
434523
end
435524

436-
desc "Set the push api key to use"
437-
task :set_push_api_key do
438-
@key = ENV['key'] or raise "No key provided"
439-
puts "Setting push api key in appsignal_key.env"
440-
File.write "appsignal_key.env", render_erb("support/templates/appsignal_key.env.erb")
441-
end
442-
443525
desc "Install bundled processmon"
444526
task :install_processmon do
445527
run_command("cd support/processmon && ./build.sh")

appsignal_key.local.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
APPSIGNAL_PUSH_API_KEY=00000000-0000-0000-0000-000000000000
2+
APPSIGNAL_PUSH_API_ENDPOINT=http://host.docker.internal:5001
3+
APPSIGNAL_LOGGING_ENDPOINT=http://host.docker.internal:5002

appsignal_key.staging.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
APPSIGNAL_PUSH_API_ENDPOINT=https://push.staging.lol/
2+
APPSIGNAL_LOGGING_ENDPOINT=https://error-tracker.staging.lol/

support/templates/README.md.erb

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,32 @@ Next, checkout the integrations locally:
1313
rake integrations:clone
1414
```
1515

16-
Generate an environment file using a valid push api key you
17-
can get on [AppSignal](https://appsignal.com):
16+
Pick the environment to send data to. The `local` and `staging` environments
17+
work out of the box:
1818

1919
```
20-
rake global:set_push_api_key key=<key>
20+
rake env:local
21+
rake env:staging
22+
```
23+
24+
Switching writes an `appsignal_key.<name>.env` file (seeded from a committed
25+
`appsignal_key.<name>.env.example` default when there is one) and copies it into
26+
`appsignal_key.env`, the file every test setup reads, tagging it with an
27+
`# ENV: <name>` marker. The active environment's contents are printed on boot,
28+
so you can always see which one is in use.
29+
30+
Pass a push api key (you can get one on [AppSignal](https://appsignal.com)) to
31+
set it for that environment while switching; it's remembered on later switches:
32+
33+
```
34+
rake env:prod key=<key>
35+
```
36+
37+
`env:local`, `env:staging` and `env:prod` are shortcuts for the general form,
38+
which works for any environment name:
39+
40+
```
41+
rake env=<name> key=<key> env:switch
2142
```
2243

2344
To start a test setup:

support/templates/appsignal_key.env.erb

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)