Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Config Vars #21

Closed
wants to merge 7 commits into from
Closed
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
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,43 @@ when accessing `/foo`, `X-Foo` will have the value `"foo"` and `X-Bar` will not
* Custom Routes
* 404

### Config Vars
The buildpack will read any env vars that are prefixed with `HEROKU_STATIC_` and write out a file accessible at `/--/env.js` from your application. Since this is publicly accessible, do not put any secrets that are meant to be private. This JavaScript file, just creates a JavaScript object, `__env`, on `window`. For instance, if the heroku app was setup with this:

```sh
$ heroku config:set HEROKU_STATIC_FOO=foo BAR=bar
```

and there was an `index.html` page:

```html
<html>
<head>
<script src="/--/env.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<body>
<p id="foo">Replace Me</p>
<p id="bar">Replace Me</p>
</body>
<script type="text/javascript">
$(document).ready(function() {
$("#foo").text(window.__env.FOO);
$("#bar").text(window.__env.BAR);
});
</script>
</html>
```

The `#foo` paragraph tag would have it's text property replaced with foo, but the `#bar` paragraph tag would not.

A `/--/env.json` file is also produced and can be used instead. The contents for the example above would be:

```json
{
"FOO": "foo",
}
```

## Testing
For testing we use Docker to replicate Heroku locally. You'll need to have [it setup locally](https://docs.docker.com/installation/). We're also using rspec for testing with Ruby. You'll need to have those setup and install those deps:

Expand Down
1 change: 1 addition & 0 deletions scripts/boot
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ case $(ulimit -u) in
esac

"${HERE}/config/make-config"
"${HERE}/config/make-env"

# make a shared pipe; we'll write the name of the process that exits to it once
# that happens, and wait for that event below this particular call works on
Expand Down
23 changes: 23 additions & 0 deletions scripts/config/make-env
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env ruby

require 'json'
require 'fileutils'
require_relative 'lib/nginx_config'

REGEX = /^HEROKU_STATIC_/
USER_CONFIG = 'static.json'

vars = {}
ENV.each do |key, value|
vars[key.sub(REGEX, '')] = value if key.match(REGEX)
end


config = NginxConfig.new(USER_CONFIG)
Tuple = Struct.new(:file, :contents)
js = Tuple.new("#{config.root}/--/env.js", "window.__env = #{vars.to_json}")
json = Tuple.new("#{config.root}/--/env.json", vars.to_json)

FileUtils.mkdir_p(File.dirname(js.file))
File.write(js.file, js.contents)
File.write(json.file, json.contents)
12 changes: 12 additions & 0 deletions spec/fixtures/env_vars/public_html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<head>
<script src="/--/env.js"></script>
<script src="/js/jquery-2.1.4.min.js"></script>
</head>
<body>
<p id="foo">Replace Me</p>
<p id="bar">Replace Me</p>
<p id="secret">Replace Me</p>
</body>
<script src="/js/onload.js"></script>
</html>
4 changes: 4 additions & 0 deletions spec/fixtures/env_vars/public_html/js/jquery-2.1.4.min.js

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions spec/fixtures/env_vars/public_html/js/onload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$(document).ready(function() {
$("#foo").text(window.__env.FOO);
$("#bar").text(window.__env.BAR);
$("#secret").text(window.__env.SECRET);
});
3 changes: 3 additions & 0 deletions spec/fixtures/env_vars/static.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"root": "public_html"
}
12 changes: 12 additions & 0 deletions spec/fixtures/env_vars_custom_routes/public_html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<head>
<script src="/--/env.js"></script>
<script src="/js/jquery-2.1.4.min.js"></script>
</head>
<body>
<p id="foo">Replace Me</p>
<p id="bar">Replace Me</p>
<p id="secret">Replace Me</p>
</body>
<script src="/js/onload.js"></script>
</html>

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions spec/fixtures/env_vars_custom_routes/public_html/js/onload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$(document).ready(function() {
$("#foo").text(window.__env.FOO);
$("#bar").text(window.__env.BAR);
$("#secret").text(window.__env.SECRET);
});
5 changes: 5 additions & 0 deletions spec/fixtures/env_vars_custom_routes/static.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"routes": {
"/**": "index.html"
}
}
11 changes: 11 additions & 0 deletions spec/fixtures/env_vars_json/public_html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<html>
<head>
<script src="/js/jquery-2.1.4.min.js"></script>
</head>
<body>
<p id="foo">Replace Me</p>
<p id="bar">Replace Me</p>
<p id="secret">Replace Me</p>
</body>
<script src="/js/onload.js"></script>
</html>

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions spec/fixtures/env_vars_json/public_html/js/onload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$(document).ready(function() {
$.getJSON("/--/env.json", function(data) {
$("#foo").text(data.FOO);
$("#bar").text(data.BAR);
$("#secret").text(data.SECRET);
});
});
3 changes: 3 additions & 0 deletions spec/fixtures/env_vars_json/static.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"root": "public_html"
}
11 changes: 11 additions & 0 deletions spec/fixtures/env_vars_json_custom_routes/public_html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<html>
<head>
<script src="/js/jquery-2.1.4.min.js"></script>
</head>
<body>
<p id="foo">Replace Me</p>
<p id="bar">Replace Me</p>
<p id="secret">Replace Me</p>
</body>
<script src="/js/onload.js"></script>
</html>

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$(document).ready(function() {
$.getJSON("/--/env.json", function(data) {
$("#foo").text(data.FOO);
$("#bar").text(data.BAR);
$("#secret").text(data.SECRET);
});
});
6 changes: 6 additions & 0 deletions spec/fixtures/env_vars_json_custom_routes/static.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"root": "public_html",
"routes": {
"/**": "index.html"
}
}
114 changes: 113 additions & 1 deletion spec/simple_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
app.destroy
end

let(:app) { AppRunner.new(name, env, @debug) }
let(:app) { AppRunner.new(name, env, @debug, ENV['CIRCLECI']) }

let(:name) { "hello_world" }
let(:env) { Hash.new }
Expand Down Expand Up @@ -509,4 +509,116 @@
end
end
end

describe "env vars" do
let(:env) do
{
"SECRET" => "OMG",
"HEROKU_STATIC_FOO" => "f00",
"HEROKU_STATIC_BAR" => "b4r"
}
end

context "simple" do
context "env.js" do
let(:name) { "env_vars" }

it "should setup envs accessible to the frontend app" do
response = app.get("/--/env.js")

expect(response.code).to eq("200")

app.run do
app.test_js(name: "env vars get set", num: 3, path: "/index.html", content: <<-JS)
test.assertEval(function() {
return $('#foo').text() === "#{env["HEROKU_STATIC_FOO"]}"
}, "#foo has changed values");
test.assertEval(function() {
return $('#bar').text() === "#{env["HEROKU_STATIC_BAR"]}"
}, "#bar has changed values");
test.assertEval(function() {
return $('#secret').text() === "Replace Me"
}, "#secret has not changed values");
JS
end
end
end

context "env.json" do
let(:name) { "env_vars_json" }

it "should setup envs accessible to the frontend app" do
response = app.get("/--/env.json")

expect(response.code).to eq("200")

app.run do
app.test_js(name: "env vars get set", num: 3, path: "/index.html", content: <<-JS)
test.assertEval(function() {
return $('#foo').text() === "#{env["HEROKU_STATIC_FOO"]}"
}, "#foo has changed values");
test.assertEval(function() {
return $('#bar').text() === "#{env["HEROKU_STATIC_BAR"]}"
}, "#bar has changed values");
test.assertEval(function() {
return $('#secret').text() === "Replace Me"
}, "#secret has not changed values");
JS
end
end
end
end

context "custom routes" do
context "env.js" do
let(:name) { "env_vars_custom_routes" }

it "should setup envs accessible to the frontend app" do
response = app.get("/--/env.js")

expect(response.code).to eq("200")

app.run do
app.test_js(name: "env vars get set", num: 3, path: "/foo", content: <<-JS)
test.assertEval(function() {
return $('#foo').text() === "#{env["HEROKU_STATIC_FOO"]}"
}, "#foo has changed values");
test.assertEval(function() {
return $('#bar').text() === "#{env["HEROKU_STATIC_BAR"]}"
}, "#bar has changed values");
test.assertEval(function() {
return $('#secret').text() === "Replace Me"
}, "#secret has not changed values");
JS
end
end
end

context "env.json" do
let(:name) { "env_vars_json_custom_routes" }

it "should setup envs accessible to the frontend app" do
response = app.get("/--/env.json")

expect(response.code).to eq("200")

app.run do
app.test_js(name: "env vars get set", num: 3, path: "/foo", content: <<-JS)
test.assertEval(function() {
return $('#foo').text() === "#{env["HEROKU_STATIC_FOO"]}"
}, "#foo has changed values");
test.assertEval(function() {
return $('#bar').text() === "#{env["HEROKU_STATIC_BAR"]}"
}, "#bar has changed values");
test.assertEval(function() {
return $('#secret').text() === "Replace Me"
}, "#secret has not changed values");
JS
end
end
end

end

end
end
Loading