Skip to content
This repository has been archived by the owner on Jul 15, 2024. It is now read-only.

Commit

Permalink
feat: monorepo setup (#337)
Browse files Browse the repository at this point in the history
  • Loading branch information
KagChi authored Feb 13, 2024
1 parent a4475b8 commit 0a83719
Show file tree
Hide file tree
Showing 63 changed files with 536 additions and 265 deletions.
97 changes: 83 additions & 14 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,87 @@
name: Build & Push to container registry
name: Build & Push Docker Image to container image registry

on:
release:
types: [created]
push:
branches:
- "**"
pull_request:
branches:
- "**"
paths:
- "Dockerfile"
workflow_call:
inputs:
ADD_FLAVOR:
description: "Whether to add flavor (only -dev atm) to the image tag"
type: boolean
required: false
default: true
NO_CACHE:
description: "Whether to use build cache"
type: boolean
required: false
default: false
SCOPE:
description: "Scope of the image (e.g. 'bot')"
type: string
required: true

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

jobs:
docker:
uses: nezuchan/workflows/.github/workflows/docker-build.yml@main
secrets: inherit
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
scope: ${{ fromJson(inputs.SCOPE) }}
steps:
- name: Check Out Repo
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 2

#- name: Set up QEMU (We don't need QEMU, because we don't build images for platforms other than linux/amd64, which is our current native arch in our infra
# uses: docker/[email protected]

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

- name: Login to GitHub Container Registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
if: ${{ github.event_name != 'pull_request' }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract tag name
id: tags
if: ${{ github.event_name == 'release' }}
run: echo ::set-output name=name::${GITHUB_REF##*/}

- name: Extract flavor
id: flavor
if: ${{ inputs.ADD_FLAVOR == true }}
run: if [ "${{ github.event_name }}" = "release" ]; then echo ::set-output name=name::; else echo ::set-output name=name::-dev; fi

- name: Generate Docker image metadata
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
id: img_meta
with:
flavor: |
latest=auto
suffix=${{ steps.flavor.outputs.name }}
images: ghcr.io/nezuchan/${{ matrix.scope }}
tags: |
${{ steps.tags.outputs.name }}
latest
- name: Build and push
id: docker_build
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: ./
tags: ${{ steps.img_meta.outputs.tags }}
labels: ${{ steps.img_meta.outputs.labels }}
push: ${{ github.event_name != 'pull_request' }}
build-args: |
"SCOPE=@nezuchan/${{ matrix.scope }}"
cache-from: type=gha,mode=max
cache-to: type=gha,mode=max
no-cache: ${{ inputs.NO_CACHE == true }}
12 changes: 12 additions & 0 deletions .github/workflows/services-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Release services

on:
release:
types: [created]

jobs:
docker:
uses: ./.github/workflows/docker.yml
with:
scope: '["kanao-gateway"]'
secrets: inherit
45 changes: 45 additions & 0 deletions .github/workflows/services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright 2023 Hazmi35 (https://github.com/Hazmi35)
name: Services Nightly Builds

on:
push:
branches:
- main
paths:
- "Dockerfile"
- "services/**"
pull_request:
branches:
- main
paths:
- "Dockerfile"

jobs:
build:
runs-on: ubuntu-latest
outputs:
folders: ${{ steps.json.outputs.folders }}
steps:
- name: Check Out Repo
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
fetch-depth: 2
- name: List changed folders
id: changed
run: |
echo ::set-output name=folders::$(git diff --name-only HEAD~1 HEAD | grep -E 'services/.*' | cut -d'/' -f2 | sort | uniq | tr '\n' ',' | sed 's/,$//')
- name: List all folders if no changes
if: steps.changed.outputs.folders == ''
id: all
run: |
echo ::set-output name=folders::$(ls services | tr '\n' ',' | sed 's/,$//')
- name: Turn output into JSON array
id: json
run: |
echo ::set-output name=folders::[$(echo ${{ steps.changed.outputs.folders || steps.all.outputs.folders }} | sed 's/,/","/g;s/^/"/;s/$/"/')]
docker:
needs: build
uses: ./.github/workflows/docker.yml
with:
scope: ${{ needs.build.outputs.folders }}
secrets: inherit
Empty file added .turbo/cookies/0.cookie
Empty file.
Empty file added .turbo/cookies/1.cookie
Empty file.
55 changes: 39 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,52 @@
FROM ghcr.io/hazmi35/node:20-dev-alpine as build-stage
# Copyright 2023 Hazmi35 (https://github.com/Hazmi35)
FROM ghcr.io/hazmi35/node:20-dev-alpine as dev

LABEL name "NezukoChan Gateway (Docker Build)"
LABEL maintainer "KagChi"
# Prepare with corepack (experimental feature)
RUN corepack enable

RUN corepack enable && corepack prepare pnpm@latest
# Prepare
FROM dev as prepare

COPY package*.json .
COPY pnpm-lock.yaml .

RUN pnpm install --frozen-lockfile
ARG SCOPE
WORKDIR /prepare

# Scoped install for monorepo
RUN npm install --global turbo
COPY . .
RUN turbo prune --scope=${SCOPE} --docker
RUN cp -r tsconfig* /prepare/out/json

# Build the project
FROM dev AS builder

WORKDIR /builder

# Set NPM_CONFIG_USERCONFIG build args
ARG SCOPE

# First install the dependencies (as they change less often)
COPY --from=prepare /prepare/out/json/ .
COPY --from=prepare /prepare/out/pnpm-lock.yaml ./pnpm-lock.yaml

# Install dependencies
RUN pnpm install --frozen-lockfile

# Build the project
COPY --from=prepare /prepare/out/full/ .
RUN pnpm run build

RUN pnpm prune --production
# Deploy the service
RUN pnpm deploy -P --filter=${SCOPE} /out

# Get ready for production
FROM ghcr.io/hazmi35/node:20-alpine

LABEL name "NezukoChan Gateway Production"
LABEL maintainer "KagChi"
LABEL name "${SCOPE}"

COPY --from=build-stage /tmp/build/package.json .
COPY --from=build-stage /tmp/build/pnpm-lock.yaml .
COPY --from=build-stage /tmp/build/node_modules ./node_modules
COPY --from=build-stage /tmp/build/dist ./dist
# Copy needed files
COPY --from=builder /out/package.json .
COPY --from=builder /out/node_modules ./node_modules
COPY --from=builder /out/dist ./dist

CMD ["node", "dist/index.js"]
# Start the app with node
CMD ["npm", "start"]
29 changes: 0 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,4 @@

</div>

# Requirements
- NodeJS 16+

# Features
- Zero downtime deployments, You will almost never need to restart the gateway service, allowing absolute 100% uptime for your bot. Even when a restart is required, kanao will resume the sessions, so you will not lose a single event.
- Big Bot Sharding support
- Docker replica

# Docker Replica

To deploy replica the container must connected to docker sock in order know which replica in they are
```yaml
version: '3.8'

services:
kanao:
deploy:
resources:
limits:
memory: "256M"
replicas: ${GATEWAY_REPLICA_COUNT:-3}
restart: always
image: 'ghcr.io/nezuchan/kanao:latest'
env_file:
- .env
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
Being used in production by NezukoChan, Musical Tune, and more.
64 changes: 12 additions & 52 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,61 +1,21 @@
{
"name": "@nezuchan/kanao",
"version": "4.0.0",
"description": "A standalone service for connecting to the Discord gateway.",
"name": "kanao",
"version": "1.0.0",
"description": "A standalone service for connecting to the Discord gateway",
"type": "module",
"scripts": {
"build": "turbo run build",
"lint": "turbo run lint",
"lint:fix": "turbo run lint:fix"
},
"keywords": [],
"author": "",
"license": "GPL-3.0",
"author": "KagChi",
"type": "module",
"main": "dist",
"scripts": {
"build": "rimraf dist && swc ./src -d dist --config-file .swcrc --strip-leading-paths",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"start": "node -r dotenv/config dist/index.js",
"start:dev": "npm run build && node -r dotenv/config dist/index.js"
},
"dependencies": {
"@discordjs/collection": "^2.0.0",
"@discordjs/rest": "^2.2.0",
"@discordjs/ws": "^1.0.2",
"@nezuchan/constants": "^0.8.0",
"@nezuchan/utilities": "^0.6.2",
"@sapphire/pieces": "^4.2.2",
"@sapphire/result": "^2.6.6",
"@sapphire/time-utilities": "^1.7.12",
"@sapphire/utilities": "^3.15.3",
"@skyra/start-banner": "^2.0.1",
"amqp-connection-manager": "^4.1.14",
"amqplib": "^0.10.3",
"bufferutil": "^4.0.8",
"discord-api-types": "^0.37.69",
"dockerode": "^4.0.2",
"dotenv": "^16.4.3",
"drizzle-orm": "^0.29.3",
"gradient-string": "^2.0.2",
"pino": "^8.18.0",
"pino-pretty": "^10.3.1",
"postgres": "^3.4.3",
"prometheus-middleware": "^1.3.3",
"tslib": "^2.6.2",
"utf-8-validate": "^6.0.3"
},
"devDependencies": {
"@hazmi35/eslint-config": "^13.3.1",
"@swc/cli": "^0.3.9",
"@swc/core": "^1.4.0",
"@types/amqplib": "^0.10.4",
"@types/dockerode": "^3.3.23",
"@types/gradient-string": "^1.1.5",
"@types/node": "^20.11.17",
"@vladfrangu/async_event_emitter": "^2.2.4",
"drizzle-kit": "^0.20.14",
"eslint": "^8.56.0",
"rimraf": "^5.0.5",
"turbo": "^1.12.3",
"typescript": "^5.3.3"
},
"optionalDependencies": {
"ioredis": "^5.3.2",
"pino-loki": "^2.2.1",
"zlib-sync": "^0.1.9"
}
}
Loading

0 comments on commit 0a83719

Please sign in to comment.