Deploying a Git Subdirectory to Heroku
Tags: node, tutorial, git, heroku
Published: 2022-01-11 19:26:11

<figure>
![Mutombo No Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2fxelxnsr5iusf3fiwal.jpg)
<figcaption>Not in Heroku's house</figcaption>
</figure>
Deploying your app to Heroku is stressful enough. If you have a subdirectory that you want to deploy by trying to push the whole repo you're gonna have a bad time.

_Well why can't I deploy the whole repo?_

Well, for starters, Heroku doesn't like that, and it'll let you know exactly why by showing you the following errors.
<figure>
![Buildpack Error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ucwc70h74soptprzypk.png)
<figcaption>It's not you it's your buildpack</figcaption>
</figure>

My first instinct was to (cry) manually set the appropriate buildpack for a node.js server as mentioned by Heroku's [Dev Center](https://devcenter.heroku.com/articles/buildpacks). However, Heroku states that...

_By default, these buildpacks will be searched in this order until a match is detected and used to compile your app._

So there really isn't any need for me to manually set the buildpack (I did it anyways bc I'm paranoid like that).
```
heroku buildpacks:set heroku/nodejs
```

So now I've manually set the buildpack to Node.js and tried pushing this bad boy to Heroku (After committing of course). _Fingers crossed_

<figure>
![Push rejected error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uencpl11m3etwegd1i7w.png)
<figcaption>Feelsbadman</figcaption>
</figure>
Luckily, the errors give us a clue as to what the problem is. In this case, it looks like I'm trying to deploy a repo with multiple directories. If you look at Heroku's [Dev Center](https://devcenter.heroku.com/articles/deploying-nodejs) once again you'll see that:

_Heroku Node.js support will only be applied when the application has a `package.json` file in the <u>root directory</u>._

<figure>
![Directory errors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wl69ckbpafpjr7c9ikc2.png)
<figcaption>That's a lot of red...</figcaption>
</figure>

So in my case, I want to deploy one specific subdirectory that has a `package.json` file. But instead I'm trying to deploy the entire repo which doesn't have a `package.json` file in it and in effect making Heroku bug out.

## The Fix
_Can you just tell me what to do pls?_

Sure! Let's start by assuming you've completed all the Heroku prerequisites:
```
npm install -g heroku
heroku login
heroku create
heroku git:remote -a my-app
```

I was given a random name for my app by Heroku so I decided to change it.

```
heroku apps:rename my-new-app-name
```
<figure>
![Heroku rename](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sm0c1d2p3b12x5qrum2g.png)
<figcaption>What's in a name?</figcaption>
</figure>

Once renamed I make sure to update my git remotes.

```
heroku git:remote -a my-new-app-name
```
![Update git remote](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcqfjf4xat3ogl9hrjle.png)

Now for the haymaker.

```
git subtree push --prefix path/to/subdirectory heroku main
```
<figure>
![Git subtree error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bywatx3ikyz8wmv18mek.png)
<figcaption>sigh</figcaption>
</figure>

Well this is embarrassing. Looks like I need to run this command from the top level of the working tree. A couple of `cd ..`'s later and...

<figure>
![Heroku enumerating](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxj79stdxzp7c8qei8k0.png)
<figcaption>Looking good so far...</figcaption>
</figure>

<figure>
![Node.js detected](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/artb0fk23pbjwb319djz.png)
<figcaption>Heroku you so smart bb</figcaption>
</figure>

<figure>
![Heroku success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gtxe9t1obqzohut8nbq6.png)
<figcaption>Success!</figcaption>
</figure>

You have now successfully deployed your subdirectory to Heroku! Thanks for reading!
![Jim Carey beautiful](https://i.pinimg.com/originals/49/b8/14/49b814d695051f4b35d0ffb6d4d4b9c7.gif)

## Extra Credit: npm-scripts
Kudos if you're still reading. Let's say that I want to make changes to my app's frontend and backend and deploy to Heroku. Writing...
```
git subtree push --prefix path/to/subdirectory heroku main
```
...is too verbose for my taste so I'm going to add some npm-scripts to the `package.json` of my backend repo.

```javascript
{
  "scripts": {
    //...
    "build:ui": "rm -rf build && cd ../../part2/phonebook-frontend && npm run build --prod && cp -r build ../../part3/phonebook-backend",
    "deploy": "git subtree push --prefix part3/phonebook-backend heroku main",
    "deploy:full": "npm run build:ui && git add . && git commit -m uibuild && git push && npm run deploy",    
    "logs:prod": "heroku logs --tail"
  }
}
```
* The script `npm run build:ui` builds the frontend, then copies the production version under the backend repository.
* `npm run deploy` pushes the current backend to Heroku.
* `npm run deploy:full` combines the two and has the necessary git commands to update the backend repository.
* `npm run logs:prod` shows the heroku logs which comes in handy for debugging.

Please note that the paths in the script `build:ui` & `deploy` depend on the location of repositories in your file system!

### Resources and Shoutouts

* [Deploying Node JS to Heroku](https://devcenter.heroku.com/articles/deploying-nodejs)
* [Heroku Buildpacks](https://devcenter.heroku.com/articles/buildpacks)
* [Mastering Git Subtrees](https://medium.com/@porteneuve/mastering-git-subtrees-943d29a798ec)