Skip to content

Build, test, and deploy backend to production #25

Build, test, and deploy backend to production

Build, test, and deploy backend to production #25

Workflow file for this run

name: Build, test, and deploy backend to production
on:
push:
branches:
- production
paths:
- .github/workflows/node-prod.yml
- server/**
pull_request:
branches:
- production
paths:
- .github/workflows/node-prod.yml
- server/**
workflow_dispatch:
inputs:
logLevel:
description: "Log level"
required: true
default: "warning"
type: choice
options:
- info
- warning
- debug
jobs:
build-server:
runs-on: ubuntu-latest
defaults:
run:
working-directory: server
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
with:
buildkitd-flags: --debug
- uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- uses: actions/setup-node@v4
with:
node-version: 16
cache: yarn
cache-dependency-path: server/yarn.lock
- if: github.event_name == 'pull_request'
run: yarn
- if: github.event_name == 'pull_request'
run: yarn lint
- if: github.event_name == 'pull_request'
run: yarn check-format
- if: github.event_name == 'pull_request'
run: yarn test
- uses: docker/login-action@v1
if: github.event_name == 'push'
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Build and push production image
if: github.event_name == 'push'
uses: docker/build-push-action@v2
with:
context: server
push: true
tags: ghcr.io/ccmbioinfo/osmp:stable
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
deploy:
runs-on: [cheo-ri]
needs:
- build-server
if: github.ref == 'refs/heads/production'
environment: OSMP_PROD
concurrency: OSMP_PROD
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Configure SSH
id: configure
# The self-hosted runner is not ephemeral, so we load the secret key into
# an agent instead in memory. Keep track of it for further workflow steps
# and so we can clean it up and not leave orphaned processes hanging around.
#
# https://docs.docker.com/engine/context/working-with-contexts/
# This avoids passing an -H parameter to every Docker CLI call.
#
# We use `tr` to trim newlines. GITHUB_OUTPUT doesn't like multi-line strings
run: |
SSH_AGENT_EVAL=$(ssh-agent -s | tr '\012\015' ' '; echo)
eval "$SSH_AGENT_EVAL"
ssh-add - <<< "${{ secrets.DEPLOY_PRIVATE_KEY }}"
echo "ssh-agent-eval=$SSH_AGENT_EVAL" >> $GITHUB_OUTPUT
echo "ssh-agent-pid=$SSH_AGENT_PID" >> $GITHUB_OUTPUT
mkdir -p ~/.ssh
echo "${{ secrets.DEPLOY_HOST_KEY }}" > ~/.ssh/known_hosts
chmod -R g-rwx,o-rwx ~/.ssh
docker context create deploy-target --docker host=ssh://${{ secrets.DEPLOY_SSH_HOST }}
docker context use deploy-target
- name: Deploy
# Even though this is deploying to a remote Docker Engine,
# Compose uses the registry credentials of the client
env:
COMPOSE_FILE: docker-compose.prod.yaml
PROJECT_ROOT: /home/ubuntu/osmp
# Server
G4RD_AUTH_METHOD: ${{ secrets.G4RD_AUTH_METHOD }}
G4RD_PASSWORD: ${{ secrets.G4RD_PASSWORD }}
G4RD_URL: ${{ secrets.G4RD_URL }}
G4RD_USERNAME: ${{ secrets.G4RD_USERNAME }}
G4RD_REALM: ${{ secrets.G4RD_REALM }}
G4RD_GRANT_TYPE: ${{ secrets.G4RD_GRANT_TYPE }}
G4RD_TOKEN_URL: ${{ secrets.G4RD_TOKEN_URL }}
G4RD_CLIENT_ID: ${{ secrets.G4RD_CLIENT_ID }}
CMH_AZURE_CLIENT_ID: ${{ secrets.CMH_AZURE_CLIENT_ID }}
CMH_AZURE_CLIENT_SECRET: ${{ secrets.CMH_AZURE_CLIENT_SECRET }}
CMH_TOKEN_URL: ${{ secrets.CMH_TOKEN_URL }}
CMH_RESOURCE: ${{ secrets.CMH_RESOURCE }}
CMH_SCOPE: ${{ secrets.CMH_SCOPE }}
CMH_GRANT_TYPE: ${{ secrets.CMH_GRANT_TYPE }}
CMH_GENE42_SECRET: ${{ secrets.CMH_GENE42_SECRET }}
CMH_URL: ${{ secrets.CMH_URL }}
KEYCLOAK_AUTH_URL: ${{ secrets.KEYCLOAK_AUTH_URL }}
KEYCLOAK_REALM: ${{ secrets.KEYCLOAK_REALM }}
KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }}
MONGO_CONNECTION_STRING: ${{ secrets.MONGO_CONNECTION_STRING }}
SERVER_SESSION_SECRET: ${{ secrets.SERVER_SESSION_SECRET }}
# Keycloak
KEYCLOAK_DB_ADDR: ${{ secrets.KEYCLOAK_DB_ADDR }}
KEYCLOAK_DB: ${{ secrets.KEYCLOAK_DB }}
KEYCLOAK_DB_USER: ${{ secrets.KEYCLOAK_DB_USER }}
KEYCLOAK_DB_PASSWORD: ${{ secrets.KEYCLOAK_DB_PASSWORD }}
run: |
eval "${{ steps.configure.outputs.ssh-agent-eval }}"
docker-compose pull
docker-compose up -d --remove-orphans
- name: Clean up
if: always()
run: |
docker context rm -f deploy-target
eval "${{ steps.configure.outputs.ssh-agent-eval }}"
SSH_AGENT_PID="${{ steps.configure.outputs.ssh-agent-pid }}" ssh-agent -k