How we build an open source app for animal shelters
Tags: actionshackathon21, opensource, animalshelter, pets
Published: 2021-12-08 14:49:43

---
title: How we build an open source app for animal shelters
published: true
description: How we build an open source app for animal shelters and utilise GitHub Actions
tags: actionshackathon21, opensource, animalshelter, pets
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qv5b0qcqffswclrphz9a.png
---

Hi, we have been building an open source application for animal shelters https://app.petbook.lt/ for the past year and we have found great value in GitHub Actions. The application has separate Back-end and Front-end repos and they both utilise GitHub Actions notably. The application had been started as part of KAYAK WeCanCode Academy https://www.wecancode.lt/ event in Kaunas to teach the local community in Lithuania to code and at the same time create software for the common good.

This software for animal shelters is meant to help document homeless and already in-shelter animals as well as to ease the adoption of these animals.

Lately both repositories have been losing traction (since summer) resulting in only very few developers that also barely find time to build this great software. However, I hope that winning a prize in this event will bring back the enthusiasm to continue building it!

![pets-oss repos contribution statistics](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bvq2yw55dwnle57ikrlw.png)

### My Workflow
When we started this work, we thought we would have it built long ago. Like with all software estimation, right? However, this open source application still needs some work to reach the minimum viable product (MVP) stage and I will guide it until it actually reaches the MVP and then we can hand it out to shelters to be tested and gather the feedback.

When we started these repositories, I had had never used GitHub Actions and even now they seem to be shockingly useful. 

Both Back-end and Front-end repos use GitHub Actions to test and to deploy the code.

I mostly worked on the Back-end repo, thus I will mostly share my excitement in Back-end repo using GitHub Actions.

Unabashed, I am proud of our decision to always nuke and redeploy the database on deployment to simplify the database changes. This allows us to have the same structure database across local, dev, prod environments as well as "local" database within GitHub Actions. Only the entries can differ, the database description language (DDL) stays the same and it is all described in 1 SQL file https://github.com/pets-oss/pets-back/blob/main/database/1-schema.sql.

I must mention that we chose to always redeploy the database to ease the development and have all DDL in one file without any migration amendments but this is definitely not safe for a working application! We are using this path only until we reach the MVP. Later on, we would not like to redeploy the database and lose all the production entries that users have already entered!

To this I would like to add that I am also extremely proud of our approach to Dockerize this Back-end application together with a PostgreSQL database. This allows us to spin up the very same code application with a "local" database within GitHub Actions. It makes sure our tests run on the newest and robust code and database changes when making a pull request. To sum up, it ensures the very same database and code across all environments - local, dev, prod and even a "local" one in GitHub Actions Docker containers!

I am very fond of the GitHub Actions that allow to spin up Docker containers together with a database.

It is also tremendous to see the caching of libraries inside GitHub Actions.

Furthermore, both repos use Github Actions to deploy and to test the code. Back-end repo deploys to Heroku while Front-end repo deploys to GitHub Pages.

All Back-end workflows can be found here https://github.com/pets-oss/pets-back/tree/main/.github/workflows.
All Front-end workflows can be found here https://github.com/pets-oss/pets-front/tree/main/.github/workflows.

### Submission Category:

Maintainer Must-Haves, DIY Deployments

### YAML files and Repositories

Back-End deployment to Heroku https://github.com/pets-oss/pets-back/blob/main/.github/workflows/sync-prod.yml

```yaml
name: Sync
on:
  schedule:
    - cron: '0 22 * * *' # UTC time 22:00 (00:00 GMT+2)
  workflow_dispatch:

jobs:
  repo-sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          persist-credentials: false
      - name: repo-sync
        uses: repo-sync/github-sync@v2
        with:
          source_repo: "https://github.com/pets-oss/pets-back.git"
          source_branch: "main"
          destination_branch: "prod"
          github_token: ${{ secrets.GITHUB_TOKEN }}
  deploy-heroku:
    runs-on: ubuntu-latest
    needs: repo-sync
    steps:
      - name: Trigger heroku deploy [prod]
        uses: benc-uk/workflow-dispatch@v1
        with:
          workflow: Deploy Heroku [prod]
          ref: prod
          token: ${{ secrets.PERSONAL_TOKEN }}
  deploy-database:
    runs-on: ubuntu-latest
    needs: repo-sync
    steps:
      - name: Trigger database deploy [prod]
        uses: benc-uk/workflow-dispatch@v1
        with:
          workflow: Nuke & Redeploy Database [prod]
          ref: prod
          token: ${{ secrets.PERSONAL_TOKEN }}
```

Back-end pull request testing and linting https://github.com/pets-oss/pets-back/blob/main/.github/workflows/pull-request.yml

```yaml
name: Pull request checks
on: pull_request
jobs:
  integration-tests:
    name: Integration Tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Copying test env file...
        uses: canastro/copy-file-action@master
        with:
          source: ".github/workflows/test-database.env"
          target: "database.env"
      - name: Creating common.env file...
        uses: canastro/copy-file-action@master
        with:
          source: ".github/workflows/test-common.env"
          target: "common.env"
      - run: docker-compose pull
        name: Pulling pull-only docker images...
      - uses: satackey/action-docker-layer-caching@v0.0.11
        name: Caching docker image...
        continue-on-error: true
      - run: docker-compose up --build -d
        name: Building containers...
      - name: Waiting for backend...
        uses: nev7n/wait_for_response@v1
        with:
          url: 'http://localhost:8081/status'
          responseCode: 200
          timeout: 20000
          interval: 200
      - name: Running tests...
        run:  docker exec pets-back_gis-backend_1 npm run test
      - name: Dump api logs
        uses: jwalton/gh-docker-logs@v1
        if: ${{ failure() }}
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setting up node_module cache
        id: node-modules
        uses: actions/cache@v2
        with:
          path: node_modules
          key: ${{ hashFiles('**/package.json') }}-node-modules
      - name: Installing node modules...
        if: steps.node-modules.outputs.cache-hit != 'true'
        run: npm install
      - name: Running lint...
        run: npm run check-lint
```

Back-end Repo
{% github pets-oss/pets-back %}

Front-end deployment to GitHub Pages https://github.com/pets-oss/pets-front/blob/main/.github/workflows/github-pages.yml

```yaml
name: Github pages

on:
    push:
        branches:
            - main

jobs:
    install:
        name: Install with Cache setup
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v2

            - name: Setup Node
              uses: actions/setup-node@v2.1.2
              with:
                  node-version: '12.x'

            - name: Get yarn cache
              id: yarn-cache
              run: echo "::set-output name=dir::$(yarn cache dir)"

            - name: Cache dependencies
              uses: actions/cache@v2
              with:
                  path: ${{ steps.yarn-cache.outputs.dir }}
                  key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
                  restore-keys: |
                      ${{ runner.os }}-yarn-
            - run: yarn --no-progress --non-interactive

            - uses: actions/cache@v2
              id: cache-build
              with:
                  path: ./*
                  key: ${{ github.sha }}

    testUnit:
        name: Test Unit
        runs-on: ubuntu-latest
        needs: install
        steps:
            - uses: actions/cache@v2
              id: restore-install
              with:
                  path: ./*
                  key: ${{ github.sha }}
            - run: yarn test

    lint:
        runs-on: ubuntu-latest
        needs: install
        steps:
            - uses: actions/cache@v2
              id: restore-install
              with:
                  path: ./*
                  key: ${{ github.sha }}
            - run: yarn lint

    testsPass:
        name: Thank you
        runs-on: ubuntu-latest
        needs: [ testUnit, lint ]
        steps:
            - run: exit 0

    publishRelease:
        name: Build and publish release
        runs-on: ubuntu-latest
        needs: [ testsPass ]
        environment: github-pages
        env:
            REACT_APP_GRAPHQL_URL: ${{ secrets.REACT_APP_GRAPHQL_URL }}
            REACT_APP_AUTH0_DOMAIN: ${{ secrets.REACT_APP_AUTH0_DOMAIN }}
            REACT_APP_AUTH0_CLIENT_ID: ${{ secrets.REACT_APP_AUTH0_CLIENT_ID }}
            REACT_APP_AUTH0_AUTH_AUDIENCE: ${{ secrets.REACT_APP_AUTH0_AUTH_AUDIENCE }}
        steps:
            - uses: actions/cache@v2
              id: restore-install
              with:
                  path: ./*
                  key: ${{ github.sha }}
            - run: yarn build
            - name: Deploy
              uses: peaceiris/actions-gh-pages@v3
              with:
                  github_token: ${{ secrets.GITHUB_TOKEN }}
                  publish_dir: ./build
                  cname: app.petbook.lt
```

Front-end pull request testing and linting https://github.com/pets-oss/pets-front/blob/main/.github/workflows/integrate.yml

```yaml
name: 'integrate'
on: pull_request


jobs:
    test_pull_request:
        runs-on: ubuntu-latest
        steps:
            -   uses: actions/checkout@v2
            -   run: |
                    yarn --no-progress --non-interactive
            -   run: |
                    yarn run lint
            -   run: |
                    yarn run test
            -   run: |
                    yarn run build
```

Front-end Repo
{% github pets-oss/pets-front %}

### Additional Resources / Info

Both Back-end and Front-end repos are used by this still-in-development application https://app.petbook.lt/

We built and are still building this software as a team and I would like to thank and mention all the epic contributors https://dev.to/justasb, https://dev.to/psaulenas, https://dev.to/kiupelis, https://dev.to/dainiusjankunas, https://dev.to/jbk91, https://dev.to/domzic, https://dev.to/saulyz, https://dev.to/ignasposka, https://dev.to/arunaswp, https://dev.to/pergaliuke, https://dev.to/bennek

![Petbook animal list display](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p0xuvgbl6ukhx7amp11e.png)