Skip to content

API

API #473

Workflow file for this run

name: API
on:
push:
branches:
- main
tags:
- "v**"
paths-ignore:
- ".idea/**"
- "**.md"
pull_request:
branches:
- main
workflow_dispatch:
inputs: {}
env:
JAVA_VERSION: "17"
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ env.JAVA_VERSION }}
cache: gradle
- run: ./gradlew check --no-daemon
- uses: codecov/codecov-action@v3
github-release:
name: GitHub Release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
needs: tests
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- run: git fetch --prune --unshallow --tags -f
- id: tag_info
run: |
export TAG_NAME="${GITHUB_REF/'refs/tags/'/''}"
{
echo "name=$TAG_NAME";
echo "body<<EOF";
git tag --list --format='%(contents:body)' $TAG_NAME;
echo "EOF";
} >> "$GITHUB_OUTPUT"
- uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.BOT_PAT }}
name: ${{ steps.tag_info.outputs.name }}
body: ${{ steps.tag_info.outputs.body }}
deploy:
name: Deploy
if: github.event_name == 'push'
needs: tests
runs-on: ubuntu-latest
timeout-minutes: 10
env:
SCP_DEST_PATH: /tmp/${{ github.sha }}
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Fetch Git Tags
run: git fetch --prune --unshallow --tags -f
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ env.JAVA_VERSION }}
cache: gradle
- name: Install prerequisites
run: |
sudo apt-get -qq update -y
sudo apt-get -qq install -y awscli
- name: Build app
run: |
./gradlew bootJar --no-daemon
(mkdir -p jar-content; cd jar-content; jar -xf ../build/libs/*.jar;)
mkdir -p app
cp -r jar-content/BOOT-INF/lib app/lib
cp -r jar-content/META-INF app/
cp -r jar-content/BOOT-INF/classes/* app
- name: Get workflow runner's public IP
id: ip
uses: haythem/[email protected]
- name: Setup environment
run: |
# if the workflow is running on a tag, deploy on the production EC2
# host. deploy on the staging host otherwise.
mkdir conf
if [[ "$GITHUB_REF" =~ refs/tags/* ]]; then
{
echo "AWS_DEFAULT_REGION=$PROD_AWS_DEFAULT_REGION";
echo "AWS_ACCESS_KEY_ID=$PROD_AWS_ACCESS_KEY_ID";
echo "AWS_SECRET_ACCESS_KEY=$PROD_AWS_SECRET_ACCESS_KEY";
echo "AWS_EC2_HOST=$PROD_AWS_EC2_HOST";
echo "AWS_EC2_SG_ID=$PROD_AWS_EC2_SG_ID";
echo "AWS_EC2_SSH_USER=$PROD_AWS_EC2_SSH_USER";
# ssh key will be a multi-line string.
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
echo "AWS_EC2_SSH_KEY<<EOF";
echo "$PROD_AWS_EC2_SSH_KEY";
echo "EOF";
} >> "$GITHUB_ENV"
# prepare api configuration
cp deploy/conf/production.properties conf/api.properties
# write EnvironmentFile for noice-api.service
echo "$PROD_API_ENV_FILE" > conf/api.env
# write google play api key
echo "$PROD_API_GOOGLE_PLAY_API_KEY" > conf/gcp-service-account-key.json
else
{
echo "AWS_DEFAULT_REGION=$STAGING_AWS_DEFAULT_REGION";
echo "AWS_ACCESS_KEY_ID=$STAGING_AWS_ACCESS_KEY_ID";
echo "AWS_SECRET_ACCESS_KEY=$STAGING_AWS_SECRET_ACCESS_KEY";
echo "AWS_EC2_HOST=$STAGING_AWS_EC2_HOST";
echo "AWS_EC2_SG_ID=$STAGING_AWS_EC2_SG_ID";
echo "AWS_EC2_SSH_USER=$STAGING_AWS_EC2_SSH_USER";
# ssh key will be a multi-line string.
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
echo "AWS_EC2_SSH_KEY<<EOF";
echo "$STAGING_AWS_EC2_SSH_KEY";
echo "EOF";
} >> "$GITHUB_ENV"
# prepare api configuration
cp deploy/conf/staging.properties conf/api.properties
# write EnvironmentFile for noice-api.service
echo "$STAGING_API_ENV_FILE" > conf/api.env
# write google play api key
echo "$STAGING_API_GOOGLE_PLAY_API_KEY" > conf/gcp-service-account-key.json
fi
env:
PROD_AWS_DEFAULT_REGION: ${{ secrets.PROD_AWS_DEFAULT_REGION }}
PROD_AWS_ACCESS_KEY_ID: ${{ secrets.PROD_AWS_ACCESS_KEY_ID }}
PROD_AWS_SECRET_ACCESS_KEY: ${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}
PROD_AWS_EC2_HOST: ${{ secrets.PROD_AWS_EC2_HOST }}
PROD_AWS_EC2_SG_ID: ${{ secrets.PROD_AWS_EC2_SG_ID }}
PROD_AWS_EC2_SSH_KEY: ${{ secrets.PROD_AWS_EC2_SSH_KEY }}
PROD_AWS_EC2_SSH_USER: ${{ secrets.PROD_AWS_EC2_SSH_USER }}
PROD_API_ENV_FILE: ${{ secrets.PROD_API_ENV_FILE }}
PROD_API_GOOGLE_PLAY_API_KEY: ${{ secrets.PROD_API_GOOGLE_PLAY_API_KEY }}
STAGING_AWS_DEFAULT_REGION: ${{ secrets.STAGING_AWS_DEFAULT_REGION }}
STAGING_AWS_ACCESS_KEY_ID: ${{ secrets.STAGING_AWS_ACCESS_KEY_ID }}
STAGING_AWS_SECRET_ACCESS_KEY: ${{ secrets.STAGING_AWS_SECRET_ACCESS_KEY }}
STAGING_AWS_EC2_HOST: ${{ secrets.STAGING_AWS_EC2_HOST }}
STAGING_AWS_EC2_SG_ID: ${{ secrets.STAGING_AWS_EC2_SG_ID }}
STAGING_AWS_EC2_SSH_KEY: ${{ secrets.STAGING_AWS_EC2_SSH_KEY }}
STAGING_AWS_EC2_SSH_USER: ${{ secrets.STAGING_AWS_EC2_SSH_USER }}
STAGING_API_ENV_FILE: ${{ secrets.STAGING_API_ENV_FILE }}
STAGING_API_GOOGLE_PLAY_API_KEY: ${{ secrets.STAGING_API_GOOGLE_PLAY_API_KEY }}
- name: Authorize runner's SSH access to EC2 host
run: |
aws ec2 authorize-security-group-ingress --group-id "$AWS_EC2_SG_ID" \
--protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
- name: Upload app and configuration files to EC2 host
uses: appleboy/scp-action@master
with:
host: ${{ env.AWS_EC2_HOST }}
username: ${{ env.AWS_EC2_SSH_USER }}
key: ${{ env.AWS_EC2_SSH_KEY }}
source: app,conf,deploy/systemd,deploy/logrotate.d
target: ${{ env.SCP_DEST_PATH }}
rm: true
- name: Configure EC2 host to use the updated app and configurations
uses: appleboy/ssh-action@master
with:
host: ${{ env.AWS_EC2_HOST }}
username: ${{ env.AWS_EC2_SSH_USER }}
key: ${{ env.AWS_EC2_SSH_KEY }}
script_stop: true
script: |
sudo systemctl stop noice-api.service || true
sudo rm -rf /usr/local/share/noice-api /etc/noice-api
sudo mv ${{ env.SCP_DEST_PATH }}/app /usr/local/share/noice-api
sudo chown -R nobody:nogroup /usr/local/share/noice-api
sudo chmod -R 755 /usr/local/share/noice-api
sudo mv ${{ env.SCP_DEST_PATH }}/conf /etc/noice-api
sudo chown -R nobody:nogroup /etc/noice-api
sudo chmod -R 700 /etc/noice-api
sudo chown root:root ${{ env.SCP_DEST_PATH }}/deploy/logrotate.d/*
sudo chmod 644 ${{ env.SCP_DEST_PATH }}/deploy/logrotate.d/*
sudo mv ${{ env.SCP_DEST_PATH }}/deploy/logrotate.d/* /etc/logrotate.d/
sudo chown root:root ${{ env.SCP_DEST_PATH }}/deploy/systemd/*
sudo chmod 644 ${{ env.SCP_DEST_PATH }}/deploy/systemd/*
sudo mv ${{ env.SCP_DEST_PATH }}/deploy/systemd/* /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl reenable noice-api.service
sudo systemctl restart noice-api.service
sudo rm -rf ${{ env.SCP_DEST_PATH }}
- name: Revoke runner's SSH access from EC2 host
if: ${{ always() }}
run: |
aws ec2 revoke-security-group-ingress --group-id "$AWS_EC2_SG_ID" \
--protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
- name: Clean up sensitive configuration from the runner
if: ${{ always() }}
run: rm -rf conf