DEV Community

Cover image for How we build an open source app for animal shelters
AzisK
AzisK

Posted on • Updated on

How we build an open source app for animal shelters

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

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

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 }}
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

Back-end Repo

GitHub logo pets-oss / pets-back

Pet Information System Back-end

Contributor Covenant

Pet Information System Back-End


Production endpoint: https://petbook-back.herokuapp.com/graphql

Development endpoint: https://petbook-back-dev.herokuapp.com/graphql

Interactive API (dev environment only)

Development guide contents

A. Prerequisites

only if running with docker:


B1. Setup with docker (recommended)

  1. Install npm libraries with npm install command (if not installed previously).
  2. Copy and rename database.env.sample to database.env. POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB can be adjusted to your liking, but the default configuration will work as well.
  3. Copy and rename common.env.sample to common.env. Create a cloudinary account and replace the CLOUDINARY_URL variable or Set CLOUDINARY_DISABLED=true
  4. Make sure Docker is running.
  5. Run docker-compose up -d

B2. Setup without docker

  1. Download the latest…




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

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
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

Front-end Repo

GitHub logo pets-oss / pets-front

Pets Information System Front-end

Contributor Covenant

integrate

pets-front

Pets Information System Front-end

Live site is available at https://app.petbook.lt/.

Setup

Before starting the setup choose what actions you will do with the code changes. If you will keep it as a local copy - make a repository clone. If you will contribute to the project - make a repository fork and read the Contribution guideline.

The project codebase is optimized for using Visual Studio Code which can be downloaded and used with the most of popular OS. Install Prettier and ESLint extensions as these are mandatory for project codebase consistency.

Get your local copy of the repository by cloning or forking.

If not yet installed, get Node JS (> 10v) and npm. Run node -v in your terminal to check the actual Node version. If you need to be able using various Node versions for your projects, consider installing and using Node version manager




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

Top comments (0)