Skip to content

Commit c7e52fc

Browse files
committed
Add frontend
1 parent 718481b commit c7e52fc

128 files changed

Lines changed: 14622 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Build Backend
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
image_tags:
7+
required: true
8+
type: string
9+
deploy_env:
10+
required: true
11+
type: string
12+
outputs:
13+
deploy_env:
14+
value: ${{ inputs.deploy_env }}
15+
16+
env:
17+
REGISTRY: ghcr.io
18+
19+
jobs:
20+
build:
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout repository
25+
uses: actions/checkout@v4
26+
27+
- name: Set up JDK 21
28+
uses: actions/setup-java@v4
29+
with:
30+
java-version: "21"
31+
distribution: "temurin"
32+
33+
- name: Setup Gradle
34+
uses: gradle/actions/setup-gradle@v4
35+
36+
- name: Gradle clean build
37+
working-directory: backend
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
GITHUB_ACTOR: ${{ github.actor }}
41+
run: ./gradlew clean build
42+
43+
- name: Set up Docker Buildx
44+
uses: docker/setup-buildx-action@v3
45+
46+
- name: Log in to GHCR
47+
uses: docker/login-action@v3
48+
with:
49+
registry: ${{ env.REGISTRY }}
50+
username: ${{ github.actor }}
51+
password: ${{ secrets.GITHUB_TOKEN }}
52+
53+
- name: Build and push backend image
54+
uses: docker/build-push-action@v6
55+
with:
56+
context: backend
57+
platforms: linux/amd64,linux/arm64
58+
push: true
59+
tags: ${{ inputs.image_tags }}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Build Frontend
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
image_tags:
7+
required: true
8+
type: string
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
13+
jobs:
14+
build:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Docker Buildx
22+
uses: docker/setup-buildx-action@v3
23+
24+
- name: Log in to GHCR
25+
uses: docker/login-action@v3
26+
with:
27+
registry: ${{ env.REGISTRY }}
28+
username: ${{ github.actor }}
29+
password: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Build and push frontend image
32+
uses: docker/build-push-action@v6
33+
with:
34+
context: frontend
35+
platforms: linux/amd64,linux/arm64
36+
push: true
37+
tags: ${{ inputs.image_tags }}

.github/workflows/ci.yml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
release:
8+
types:
9+
- published
10+
11+
permissions:
12+
contents: read
13+
packages: write
14+
15+
env:
16+
BACKEND_IMAGE: ghcr.io/vzbot3d/vzbot-discordbot
17+
FRONTEND_IMAGE: ghcr.io/vzbot3d/vzbot-nuxt
18+
19+
jobs:
20+
detect-changes:
21+
runs-on: ubuntu-latest
22+
outputs:
23+
backend: ${{ github.event_name == 'release' || steps.filter.outputs.backend }}
24+
frontend: ${{ github.event_name == 'release' || steps.filter.outputs.frontend }}
25+
backend_tags: ${{ steps.tags.outputs.backend_tags }}
26+
frontend_tags: ${{ steps.tags.outputs.frontend_tags }}
27+
deploy_env: ${{ steps.tags.outputs.deploy_env }}
28+
29+
steps:
30+
- name: Checkout repository
31+
uses: actions/checkout@v4
32+
33+
- name: Detect changed paths
34+
uses: dorny/paths-filter@v3
35+
id: filter
36+
with:
37+
filters: |
38+
backend:
39+
- 'backend/**'
40+
frontend:
41+
- 'frontend/**'
42+
43+
- name: Determine image tags and deploy environment
44+
id: tags
45+
run: |
46+
if [[ "${GITHUB_EVENT_NAME}" == "release" ]]; then
47+
VERSION=${{ github.event.release.tag_name }}
48+
echo "backend_tags=${{ env.BACKEND_IMAGE }}:${VERSION},${{ env.BACKEND_IMAGE }}:latest" >> $GITHUB_OUTPUT
49+
echo "frontend_tags=${{ env.FRONTEND_IMAGE }}:${VERSION},${{ env.FRONTEND_IMAGE }}:latest" >> $GITHUB_OUTPUT
50+
echo "deploy_env=production" >> $GITHUB_OUTPUT
51+
else
52+
echo "backend_tags=${{ env.BACKEND_IMAGE }}:stage-${GITHUB_SHA::7},${{ env.BACKEND_IMAGE }}:stage-latest" >> $GITHUB_OUTPUT
53+
echo "frontend_tags=${{ env.FRONTEND_IMAGE }}:stage-${GITHUB_SHA::7},${{ env.FRONTEND_IMAGE }}:stage-latest" >> $GITHUB_OUTPUT
54+
echo "deploy_env=stage" >> $GITHUB_OUTPUT
55+
fi
56+
57+
build-backend:
58+
needs: detect-changes
59+
if: needs.detect-changes.outputs.backend == 'true'
60+
uses: ./.github/workflows/build-backend.yml
61+
with:
62+
image_tags: ${{ needs.detect-changes.outputs.backend_tags }}
63+
deploy_env: ${{ needs.detect-changes.outputs.deploy_env }}
64+
secrets: inherit
65+
66+
build-frontend:
67+
needs: detect-changes
68+
if: needs.detect-changes.outputs.frontend == 'true'
69+
uses: ./.github/workflows/build-frontend.yml
70+
with:
71+
image_tags: ${{ needs.detect-changes.outputs.frontend_tags }}
72+
secrets: inherit
73+
74+
deploy:
75+
runs-on: ubuntu-latest
76+
needs: [detect-changes, build-backend, build-frontend]
77+
if: always() && !failure() && !cancelled()
78+
79+
steps:
80+
- name: Checkout repository
81+
uses: actions/checkout@v4
82+
83+
- name: Copy infra files to server
84+
uses: appleboy/scp-action@v0.1.7
85+
with:
86+
host: ${{ secrets.SERVER_HOST }}
87+
username: github
88+
password: ${{ secrets.SERVER_PASSWORD }}
89+
port: ${{ secrets.SERVER_SSH_PORT }}
90+
source: "infra/docker-compose.yml,infra/deploy.sh"
91+
target: "~"
92+
93+
- name: Deploy on server
94+
uses: appleboy/ssh-action@v1.2.0
95+
with:
96+
host: ${{ secrets.SERVER_HOST }}
97+
username: github
98+
password: ${{ secrets.SERVER_PASSWORD }}
99+
port: ${{ secrets.SERVER_SSH_PORT }}
100+
script: |
101+
chmod +x ~/infra/deploy.sh
102+
~/infra/deploy.sh ${{ needs.detect-changes.outputs.deploy_env }}

frontend/.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.output
3+
.nuxt

frontend/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
BACKEND_URL=http://localhost:8080
2+
BACKEND_TOKEN=

frontend/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Nuxt dev/build outputs
2+
.output
3+
.data
4+
.nuxt
5+
.nitro
6+
.cache
7+
dist
8+
9+
# Node dependencies
10+
node_modules
11+
12+
# Logs
13+
logs
14+
*.log
15+
16+
# Misc
17+
.DS_Store
18+
.fleet
19+
.idea
20+
21+
# Local env files
22+
.env
23+
.env.*
24+
!.env.example

frontend/Dockerfile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
FROM node:20-slim AS base
2+
ENV PNPM_HOME="/pnpm"
3+
ENV PATH="$PNPM_HOME:$PATH"
4+
RUN corepack enable
5+
6+
WORKDIR /app
7+
COPY package.json pnpm-lock.yaml tsconfig.json ./
8+
9+
FROM base AS prod-deps
10+
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
11+
12+
FROM base AS build
13+
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
14+
COPY . .
15+
RUN pnpm run build
16+
17+
FROM node:lts-slim as runner
18+
19+
ENV NODE_ENV=PRODUCTION
20+
EXPOSE 3000
21+
22+
WORKDIR /app
23+
24+
COPY --from=build /app/.output .output
25+
26+
ENTRYPOINT ["node", ".output/server/index.mjs"]

frontend/README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Nuxt Minimal Starter
2+
3+
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
4+
5+
## Setup
6+
7+
Make sure to install dependencies:
8+
9+
```bash
10+
# npm
11+
npm install
12+
13+
# pnpm
14+
pnpm install
15+
16+
# yarn
17+
yarn install
18+
19+
# bun
20+
bun install
21+
```
22+
23+
## Development Server
24+
25+
Start the development server on `http://localhost:3000`:
26+
27+
```bash
28+
# npm
29+
npm run dev
30+
31+
# pnpm
32+
pnpm dev
33+
34+
# yarn
35+
yarn dev
36+
37+
# bun
38+
bun run dev
39+
```
40+
41+
## Production
42+
43+
Build the application for production:
44+
45+
```bash
46+
# npm
47+
npm run build
48+
49+
# pnpm
50+
pnpm build
51+
52+
# yarn
53+
yarn build
54+
55+
# bun
56+
bun run build
57+
```
58+
59+
Locally preview production build:
60+
61+
```bash
62+
# npm
63+
npm run preview
64+
65+
# pnpm
66+
pnpm preview
67+
68+
# yarn
69+
yarn preview
70+
71+
# bun
72+
bun run preview
73+
```
74+
75+
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

frontend/app.vue

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<template>
2+
<div v-if="!backendReachable">
3+
<LoadingPage/>
4+
</div>
5+
<div v-else>
6+
<NuxtLoadingIndicator />
7+
<NuxtLayout>
8+
<NuxtPage/>
9+
</NuxtLayout>
10+
</div>
11+
</template>
12+
13+
<script setup lang="ts">
14+
15+
import {useIntervalFn} from "@vueuse/core";
16+
import LoadingPage from "~/components/LoadingPage.vue";
17+
18+
const { data, refresh } = await useFetch<boolean>('/api/status')
19+
20+
const backendReachable = computed(() => {
21+
return data.value
22+
})
23+
24+
useIntervalFn(() => {
25+
refresh()
26+
}, 5000)
27+
28+
useHead({
29+
title: "VzBoT | Official Webpage"
30+
})
31+
</script>

0 commit comments

Comments
 (0)