Question

# ./circle.yml

deployment:
  acceptance:
    branch: master
    commands:
      - ./script/heroku_deploy.sh thecatch-staging:
          timeout: 300

# ./script/heroku_deploy.sh

#!/bin/sh -e
APP_NAME=$1

git remote add heroku git@heroku.com:$APP_NAME.git
git fetch heroku
MIGRATION_CHANGES=$(git diff HEAD heroku/master --name-only -- db | wc -l)
echo "$MIGRATION_CHANGES db changes."

PREV_WORKERS=$(heroku ps --app $APP_NAME | grep "^worker." | wc -l | tr -d ' ')

# migrations require downtime so enter maintenance mode
if test $MIGRATION_CHANGES -gt 0; then
  heroku maintenance:on --app $APP_NAME

  # Make sure workers are not running during a migration
  heroku scale worker=0 --app $APP_NAME
fi

# deploy code changes (and implicitly restart the app and any running workers)
git push heroku $CIRCLE_SHA1:refs/heads/master

# run database migrations if needed and restart background workers once finished
if test $MIGRATION_CHANGES -gt 0; then
  heroku run rake db:migrate db:seed --app $APP_NAME
  heroku scale worker=$PREV_WORKERS --app $APP_NAME
  heroku restart --app $APP_NAME
fi

heroku run rake cache:flush --app $APP_NAME
heroku maintenance:off --app $APP_NAME

When I push to master, circleci runs my tests, tests pass and I get the following error while deploying to Heroku:

fatal: protocol error: expected old/new/ref, got 'shallow 0966e85b342cb4daaace954d68c928acf743490f'
fatal: The remote end hung up unexpectedly

Full deploy log:

$ ./script/heroku_deploy.sh thecatch-staging
 Warning: Permanently added 'heroku.com,50.19.85.132' (RSA) to the list of known hosts.

Fetching repository, done.
From heroku.com:thecatch-staging
 * [new branch]      master     -> heroku/master
0 db changes.
Warning: Permanently added the RSA host key for IP address '50.19.85.156' to the list of known hosts.

Fetching repository, done.
Unshallowing... 
remote: Counting objects: 2126, done.
remote: Compressing objects: 100% (614/614), done.
remote: Total 1810 (delta 1255), reused 1663 (delta 1140)
Receiving objects: 100% (1810/1810), 1006.69 KiB | 330.00 KiB/s, done.
Resolving deltas: 100% (1255/1255), completed with 130 local objects.
Counting objects: 55, done.
Delta compression using up to 32 threads.
Compressing objects: 100% (39/39), done.
Writing objects: 100% (41/41), 4.40 KiB | 0 bytes/s, done.
Total 41 (delta 27), reused 0 (delta 0)
fatal: protocol error: expected old/new/ref, got 'shallow 0966e85b342cb4daaace954d68c928acf743490f'
fatal: The remote end hung up unexpectedly
./script/heroku_deploy.sh thecatch-staging returned exit code 128action ./script/heroku_deploy.sh thecatch-staging failed
Was it helpful?

Solution

You are using git push heroku $CIRCLE_SHA1:refs/heads/master instead of git push heroku $CIRCLE_SHA1:master in your code.

Also, you are defining the $CIRCLE_SHA1 variable, but its value is not being assigned anywhere in your script.

Correct these two and check if that solves your problem.

OTHER TIPS

For anyone trying this out, after talking to Circle folks, I had to change the timeout call to be between brackets circle.yml to

deployment:
  production:
    branch: master
    commands:
      - ./script/heroku_deploy.sh myHerokuApp $CIRCLE_SHA1: { timeout: 400 }
      - ./script/heroku_deploy_restart.sh myHerokuApp

My script now has takes variables, appName and CircleSha:

#!/bin/sh -e
APP_NAME=$1
CIRCLE_SHA1=$2

#and so on...

(I also had problems with the PREV_WORKERS line not working as expected so I hard coded it in my case.)

Another issue to consider is that in the case of a timeout you might not be restarting workers or putting application back off maintenance mode.

Thus I move those commands to a second script called heroku_deploy_restart.sh

#!/bin/sh -e
APP_NAME=$1

#restart background workers once finished
heroku scale worker=1 --app $APP_NAME
heroku run rake memcached:flush --app $APP_NAME
heroku maintenance:off --app $APP_NAME
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top