Deploying your static app to your backend repo using GitHub Actions
Our solution has two parts: a backend written in JavaScript, providing the API and a front-end created in Angular, Ionic, React or whatever is the flavor of the day. Usually you would deploy a web server to handle the URL, host the static files and have it redirect the /api
URL to our backend.
However there might be reasons (or that) that we can't or don't want to access the web server and need to serve your front-end app from the /static
directory of our backend.
Planning and a little YAML
Merging the two repositories seems initially an easy option, it just would break our workflows, so a different solution needs to be devised. The ask is simple:
Whenever a change happens in the main
branch of the front-end application (mostly through an approved pull request), the application should be build and the result transfered to the back-end application where a pull request merges it into main
. Duplicate approvals shall be avoided. So we need:
- Automatic build on push to main
- Pull / Push the bundle changes from front-end to the back-end
- Create a pull request and merge it in back-end
GitHub Actions
Our solution's repositories are hosted on GitHub, so I thought, GitHub Actions could be a simple solution. Starting is quite easy. We create a .github/workflows
directory in our repo and populate it with yaml files.
To give us a head start, the GitHub Marketplace lists over 5000 actions, that we can utilize. This makes typical tasks quite easy, once we find the right tool.
Since we will be working cross repository, we need a Personal Access Token (PAT). As a good practise we limit the token's permission to repo access only. Alternatively we could use a Deploy Key.
Our first workflow does nothing spectacular, short of the last step:
name: Reconcile front and backend
on:
push:
branches: [main]
jobs:
buildui:
name: Building UI
runs-on: ubuntu-latest
steps:
- name: Checkout UI
uses: actions/checkout@v2
- name: Deploy NodeJS
uses: actions/setup-node@v1
with:
node-version: "12.x"
- run: npm install
- run: npm run build --if present
- run: npm test
- name: Git schenigans
shell: bash
env:
GITHUB_TOKEN: ${{secrets.UI_PUSH_TOKEN }}
REPO2: acme/back-end
GITHUB_USER: john-doe
run: |
.github/pushRepo.sh
GitHub will run step by step and terminate if one of the steps fail. Our last step is a shell script. I found it easier to get what I need there, than trying the various market place options. In a nutshell:
- register the backend as sub-module. Since the front-end repo never goes back, no harm is done
- copy the files
- commit and push
#!/bin/bash
# Send UI back to a new branch in backend
now=$(date +"%Y-%m-%d_%H-%M")
message="[UI Commit] ${now}"
# Step1 clone backend
git submodule add https://${GITHUB_USER}:${GITHUB_TOKEN}@github.com/$REPO2 backend
# Step3 update UI
rm -rf backend/static/ui
mkdir -p backend/static/ui
cp build/* backend/static/ui/
cd backend
git config user.email "automation@acme.com"
git config user.name "Acme automation"
git add --all
git commit -m "$message"
git checkout -b ui/ui-$now
git push -u origin ui/ui-$now
The changes now appear in the back-end repository in a new branch carrying a time stamp it its name. Next stop are pull request and auto-merge. For the pull request we use autopull-ui.yml
in the back-end repository:
name: Auto pull request on UI branches
on:
push:
branches: ui/*
jobs:
pullrequest:
name: Create pull request
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Make pullR
uses: repo-sync/pull-request@v2.3
with:
destination_branch: "main"
pr_label: "ui,automerge"
github_token: ${{secrets.UI_PUSH_TOKEN }}
The key values here are the labels ui
and automerge
which set the stage for auto-merge-ui.yml
that takes the pull request and merges it in. When approvers for the two repositories are different, we would skip that step:
name: automerge ui
on:
pull_request:
types:
- labeled
- unlabeled
- synchronize
- opened
- edited
- ready_for_review
- reopened
- unlocked
pull_request_review:
types:
- submitted
check_suite:
types:
- completed
status: {}
jobs:
automerge:
runs-on: ubuntu-latest
steps:
- name: automerge
uses: "pascalgn/automerge-action@v0.11.0"
env:
GITHUB_TOKEN: ${{secrets.UI_PUSH_TOKEN }}
MERGE_DELETE_BRANCH: true
MERGE_LABELS: automerge,ui
ANd there you have it: two repositories, one approval for changes. Make sure you check carefull when trying yourself
As usual YMMV!
Posted by Stephan H Wissel on 04 October 2020 | Comments (0) | categories: GitHub NodeJS NodeRED