Skip to content

Instantly share code, notes, and snippets.

@richardkmichael
Created October 18, 2012 14:11
Show Gist options
  • Save richardkmichael/3912072 to your computer and use it in GitHub Desktop.
Save richardkmichael/3912072 to your computer and use it in GitHub Desktop.
#!/bin/bash
# FIXME: Can't node write a PID file? This hopes the current user doesn't run more
# than one node process.
kill_node_server() {
kill -9 $(ps | grep -m 1 "node" | cut -c 1-5)
}
setup_heroku() {
gem install heroku -d --no-rdoc --no-ri
# export HEROKU_API_KEY=<api key>
heroku keys:clear
yes | heroku keys:add
sleep 3
}
# FIXME: Environments need a fail-consequence action, then the "else"
# can move inside this function too.
run_tests_in_environment() {
local environment=$1
NODE_ENV=$environment ./run_tests.sh $environment
}
print_banner(){
echo ""
echo ""
echo "---------- $1 ----------"
}
print_banner 'DEVELOPMENT'
# Node server removed:
# Do we really need to run a node server? run_tests.sh is just using cucumber.
if ! run_tests_in_environment development; then
echo "DEVELOPMENT tests fail."
exit 1
fi
print_banner 'STAGING'
# FIXME: The gem command is not the Unix-way(tm), so this won't work.
gem list heroku || setup_heroku
deploy_to_heroku_environment(){
local environment=$1
echo ""
echo "Started DEPLOYMENT to the ${environment} server"
git remote rm heroku >/dev/null 2>&1
yes | ruby travis-deployer.rb heroku-app-${environment}
git remote -v
yes | git push heroku master 2>&1 | grep -q "Everything up-to-date"
PUSH_TO_HEROKU_RESULT=$?
if [ $PUSH_TO_HEROKU_RESULT -eq 0 ]
then
# To really test for this, read the latest SHA1 from master and the remote;
# the 0 exit status is an indirect test.. ?
echo "${environment} server already has latest code deployed!"
echo "STOPPING, you should look into why this happened!"
echo ""
exit 0
fi
heroku config:set NODE_ENV=${environment} --app heroku-app-${environment}
}
echo "VERIFYING the STAGING server DEPLOYMENT"
if ! run_tests_in_environment staging; then
echo "STAGING tests fail, ROLLING BACK."
heroku releases:rollback --app heroku-app-staging
exit 1
fi
echo "DEPLOYMENT to STAGING was SUCCESSFUL"
print_banner 'PRODUCTION'
echo ""
echo "Started DEPLOYMENT to the PRODUCTION server"
git remote rm heroku >/dev/null 2>&1
yes | ruby travis-deployer.rb heroku-app-production
git remote -v
yes | git push heroku master 2>&1 | grep -q "Everything up-to-date"
RESULT=$?
if [ $RESULT -eq 0 ]
then
echo "PRODUCTION server already has latest code deployed!"
echo "STOPPING, you should look into why this happened!"
echo ""
exit 0
fi
heroku config:set NODE_ENV=production --app heroku-app-production
echo "VERIFYING the PRODUCTION server DEPLOYMENT"
if ! NODE_ENV=production ./run_tests.sh PRODUCTION
then
echo "DEPLOYMENT to PRODUCTION was NOT SUCCESSFUL"
echo "ROLLING-BACK PRODUCTION"
heroku releases:rollback --app heroku-app-production
echo "ROLLING-BACK STAGING"
git remote rm heroku >/dev/null 2>&1
yes | ruby travis-deployer.rb heroku-app-staging
heroku releases:rollback --app heroku-app-staging
exit 1
fi
echo "DEPLOYMENT to PRODUCTION was SUCCESSFUL"
echo "!!! AWESOME !!!"
exit 0
run_development() {
echo "Running All Features on DEVELOPMENT"
NODE_ENV=development ./node_modules/.bin/cucumber.js tests/cucumber/features
features=$?
exit $features
}
run_staging() {
echo "Running All Features on STAGING"
curl --silent --insecure --url "https://test.example.com/hirefire" # check if heroku is up
echo ""
NODE_ENV=staging ./node_modules/.bin/cucumber.js tests/cucumber/features
features=$?
exit $features
}
run_production() {
echo "Running @verify-against-production && ~@clean-mongo-db Features on PRODUCTION"
curl --silent --url "https://example.com/hirefire" # check if heroku is up
echo ""
NODE_ENV=production ./node_modules/.bin/cucumber.js tests/cucumber/features --tags @verify-against-production --tags ~@clean-mongo-db
features=$?
exit $features
}
TARGET_ENVIRONMENT=$1
run_${TARGET_ENVIRONMENT}
#!/usr/bin/env ruby
if ARGV.empty?
puts "Please provide the Heroku app name."
exit
end
heroku_app_name = ARGV[0]
File.open(".git/config", "a") do |git_config|
git_config.puts <<-EOF
[remote "heroku"]
url = git@heroku.com:#{heroku_app_name}.git
fetch = +refs/heads/*:refs/remotes/heroku/*
EOF
end
ssh_config = File.expand_path("~/.ssh/config")
File.open(ssh_config, "a") do |ssh_config|
ssh_config.puts <<-EOF
Host heroku.com
StrictHostKeyChecking no
CheckHostIP no
UserKnownHostsFile=/dev/null
EOF
end
@richardkmichael
Copy link
Author

Re: the running Node server in development.

I did understand that you run tests locally, then staging, then production. But, I guessed the cucumber in the DEVELOPMENT case in run_tests.sh would handle the starting the development server, as cucumber in a Rails project doesn't require me to start the development Rails server separately.

In any case, if required, it would be nice to push the server-start down to hide it; it jumped out at me in the middle of the script - the other environments don't start a server (always running presumably, though, you do curl to test them -- that's a similar idea: "make sure test target server is available".).

@MarkNijhof
Copy link

The reason that my script doesn't do this is because in development I most of the time have the server running already and then it would fail to start on the same port, but I am open to suggestions on that one. Happy to kill the server before starting it again as well as this would mean all new code will be loaded.

The curl is also because Heroku has a long spinn up time and I don't want my first test to timeout because of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment