dokku / github-action

MIT License
165 stars 30 forks source link

Monorepo deploy support #17

Closed raghavmri closed 3 years ago

raghavmri commented 3 years ago

I am currently having a monorepo where I want to deploy a specific app that is in a sub directory using the Github action. Is it possible?

yassinebridi commented 3 years ago

Yes it is possible, I don't know how you are deploying your app, but I'm using docker to do it, so here is how I do it:

name: Deploy
on:
  push:
    branches:
      - master

jobs:
  build-web:
    name: Deploy WEB(Prod)
    runs-on: ubuntu-latest
    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Run env setter script
        run: |
          source ./envSetter
          echo "::set-env name=BOTH_ENV::$BOTH"
          echo "::set-env name=API_ENV::$API"
          echo "::set-env name=WEB_ENV::$WEB"
        env:
          BEFORE: ${{ github.event.before }}
          SHA: ${{ github.sha }}

      - name: Run deploy script
        if: env.WEB_ENV == 'true' || env.BOTH_ENV == 'true'
        run: |
          source ./deploy
        env:
          GITHUB_REF: ${{ github.ref }}
          VERCEL_HOOK_PROD: ${{ secrets.VERCEL_HOOK_PROD }}

  build-api:
    name: Deploy API(Prod)
    runs-on: ubuntu-latest
    env:
      ACTIONS_ALLOW_UNSECURE_COMMANDS: true
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Run deploy script
        run: |
          source ./envSetter
          echo "::set-env name=BOTH_ENV::$BOTH"
          echo "::set-env name=API_ENV::$API"
          echo "::set-env name=WEB_ENV::$WEB"
        env:
          BEFORE: ${{ github.event.before }}
          SHA: ${{ github.sha }}

      - name: Push to dokku
        id: publish
        uses: dokku/github-action@master
        with:
          git_remote_url: ${{ secrets.SSH_URL_API }}
          ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Pushbullet Notification(if the build fails)
        uses: yassinebridi/pushbullet-action@v1.0.2
        if: steps.publish.outcome != 'success'
        env:
          PB_TOKEN: ${{ secrets.PB_TOKEN }}
          PB_TYPE: link
          PB_TITLE: Tour project Build failed
          PB_BODY: ${{github.event.head_commit.message}}
          PB_URL: https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}
      - name: Pushbullet Notification
        uses: yassinebridi/pushbullet-action@v1.0.2
        if: steps.publish.outcome == 'success'
        env:
          PB_TOKEN: ${{ secrets.PB_TOKEN }}
          PB_TYPE: link
          PB_TITLE: Tour Project is Published
          PB_BODY: ${{github.event.head_commit.message}}
          PB_URL: https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}

This is the envSetter script, to determine which packages to build and deploy:

#! /bin/bash

set -e

DIFF=$(git diff --name-only --diff-filter=AM $BEFORE $SHA)

API_CHANGED=false
WEB_CHANGED=false

API=false
BOTH=false

if echo $DIFF | grep -q "packages/api";
then
  API_CHANGED=true
  echo "Found changes in the API packages"
fi

if echo $DIFF | grep -q "packages/web";
then
  WEB_CHANGED=true
  echo "Found changes in the WEB packages"
fi

if [[ $API_CHANGED = true && $WEB_CHANGED = true ]]
then
  echo "Triggering deployment for API and WEB"
  export BOTH=true
elif [[ $API_CHANGED = true ]]
then
  echo "Triggering deployment for API"
  export API=true
elif [[ $WEB_CHANGED = true ]]
then
  echo "Triggering deployment for WEB"
  export WEB=true
else
  echo "Nothing to deploy"
  export API=false
  export BOTH=false
fi

This is the Dockerfile to deploy the API package(This Dockerfile exists in the root folder):

FROM node

WORKDIR /tour

COPY ./package.json .
COPY ./yarn.lock .
COPY ./packages/common/package.json ./packages/common/
COPY ./packages/api/package.json ./packages/api/
COPY ./packages/api/tsconfig.json ./packages/api/
COPY ./packages/api/prisma ./packages/api/prisma/

RUN yarn install --production --unsafe-perm

COPY ./packages/api/dist ./packages/api/dist/
COPY ./packages/common/dist ./packages/common/dist/

WORKDIR ./packages/api

ENV NODE_ENV production

EXPOSE 4000

CMD ["node", "dist/src/main"]

All of this is in the context of yarn workspaces.

josegonzalez commented 3 years ago

You don't need all of the above. You can specify the subdirectory to deploy via the following builder:set command to set the build-dir property:

dokku builder:set $APP build-dir some-path

You can then push your app as normal.