Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zabo-Boards CD 파이프라인 추가 #13

Merged
merged 22 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2354d9f
feat: add auth slice
jinho-choi123 Nov 24, 2023
044a1e2
feat: add authentication to board
jinho-choi123 Nov 24, 2023
cadc934
add login feature for boards
jinho-choi123 Mar 18, 2024
d7abe2d
feat: make error message popup when login fails
jinho-choi123 Mar 18, 2024
864bc98
misc: remove console log
jinho-choi123 Mar 18, 2024
78c6b8b
misc: make init content configurable
jinho-choi123 Mar 22, 2024
5eb1ccd
feat: use /api/board api instead of /api/zabo api.
jinho-choi123 Mar 22, 2024
25fa5a1
refactor: separate diff pages to diff file
jinho-choi123 Mar 22, 2024
70ca6f3
refactor: remove unnecessary loop
jinho-choi123 Mar 22, 2024
d7e6283
misc: remove finished todo comment
jinho-choi123 Mar 22, 2024
6e2cc9f
CD: add github action for prod image build
jinho-choi123 Apr 26, 2024
9172c20
fix: update vulnerable packages
jinho-choi123 Apr 26, 2024
30760c6
fix: move github action file into workflows dir
jinho-choi123 Apr 26, 2024
97faee3
CD: move yarn build to image
jinho-choi123 Apr 26, 2024
0f12908
CD: add multi-stage build and yarn-lock based build
jinho-choi123 Apr 26, 2024
8243869
misc: update yarn.lock
jinho-choi123 Apr 26, 2024
73cb62b
docs: add deploy part to readme
jinho-choi123 Apr 26, 2024
d2d61c8
feat: cleanup prev image if watchtower fetch new image
jinho-choi123 May 3, 2024
c70466a
deploy: add dotenv production key to github repo. This is safe, it do…
jinho-choi123 May 10, 2024
86c9609
CD: send slack msg when container shutdown and restart
jinho-choi123 May 10, 2024
1aaeac3
misc: gitignore .env.production for docker compose
jinho-choi123 May 10, 2024
9b1012b
misc: add d option for docker compose up
jinho-choi123 May 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SLACK_WATCHTOWER_WEBHOOK=
22 changes: 22 additions & 0 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Dockerfile for production build
FROM node:18-alpine AS builder

WORKDIR /app

COPY . .

RUN yarn --frozen-lockfile

RUN yarn build

FROM node:18-alpine

WORKDIR /app

COPY --from=builder /app/dist /app

RUN yarn global add serve

EXPOSE 80

ENTRYPOINT ["serve", "-l", "80", "/app"]
17 changes: 17 additions & 0 deletions .docker/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: "3"

services:
watch-tower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 30 --scope zabo-boards --cleanup
labels: [ "com.centurylinklabs.watchtower.scope=zabo-boards" ]
zabo-boards:
image: ghcr.io/sparcs-kaist/zabo-boards:latest
ports:
- 8888:80
labels:
- "com.centurylinklabs.watchtower.scope=zabo-boards"
- 'com.centurylinklabs.watchtower.lifecycle.pre-update=curl -X POST -H ''Content-type: application/json'' --data ''{"text":"[PROD] 업데이트를 위해 zabo-boards 서비스를 종료시켰습니다."}'' ${SLACK_WATCHTOWER_WEBHOOK}'
- 'com.centurylinklabs.watchtower.lifecycle.post-update=curl -X POST -H ''Content-type: application/json'' --data ''{"text":"[PROD] 업데이트 후 zabo-boards 서비스를 재시작하였습니다."}'' ${SLACK_WATCHTOWER_WEBHOOK}'
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## VITE_API_SERVER_URL should end without "/"
VITE_API_SERVER_URL=
VITE_ANIMATION_DURATION=
VITE_TRANSITION_INTERVAL=
VITE_TRANSITION_INTERVAL=

## put s3 url for initial content for zabo boards
VITE_INIT_CONTENT1=
VITE_INIT_CONTENT2=
8 changes: 8 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## VITE_API_SERVER_URL should end without "/"
VITE_API_SERVER_URL=https://zabo.sparcs.org/api
VITE_ANIMATION_DURATION=3200
VITE_TRANSITION_INTERVAL=10000

## put s3 url for initial content for zabo boards
VITE_INIT_CONTENT1=https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136431583315238282https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136431583315238282
VITE_INIT_CONTENT2=https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136431583315238282https://sparcs-kaist-zabo-prod.s3.ap-northeast-2.amazonaws.com/zabo/zabo-136431583315238282
5 changes: 4 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@
"prefer": "type-imports"
}
],
"arrow-body-style": ["warn"]
"arrow-body-style": ["warn"],
"jsx-a11y/label-has-associated-control": [ 2, {
"some": [ "nesting", "id" ]
}]
},
"settings": {
"import/parsers": {
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/prod-build-image.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Build docker image on tag creation

on:
push:
tags:
- "**"

jobs:
build:
name: Build and push Image to ghcr
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Docker buildX
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{runner.os}}-buildx-${{github.sha}}
restore-keys: |
${{runner.os}}-buidx-
- name: Log in to Github Container Registry
run: echo ${{secrets.GITHUB_TOKEN}} | docker login ghcr.io -u USERNAME --password-stdin
- name: Build and Push Image
id: docker-build
uses: docker/build-push-action@v5
env:
IMAGE_TAG: ${{github.ref_name}}
with:
file: ./.docker/Dockerfile
push: true
tags: |
"ghcr.io/sparcs-kaist/zabo-boards:${{ env.IMAGE_TAG }}"
"ghcr.io/sparcs-kaist/zabo-boards:latest"
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Remove old cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

### Node ###
# Logs
.idea
.uuid
logs
*.log
npm-debug.log*
Expand Down Expand Up @@ -79,11 +81,10 @@ web_modules/
# dotenv environment variable files
.env
.env.development
.env.production
.env.development.local
.env.test.local
.env.production.local
.env.local
.docker/.env.production

# parcel-bundler cache (https://parceljs.org/)
.cache
Expand Down
60 changes: 42 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
# React + TypeScript + Vite
# Zabo Boards

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
## About
Zabo Boards helps **KAIST students based** individuals or clubs advertising themselves via TV screen in open space.
While this service is open for public, **only approved groups** are able to post images.
Please submit your request in order to create a new group via our website.

Currently, two official plugins are available:
This project is being maintained by [SPARCS KAIST](https://github.com/sparcs-kaist)

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
We're expecting our users post there recruiting announcements, performance schedules, and any other events advertisments.
However, there's no strict restrictions on contents that users upload.

## Expanding the ESLint configuration
Please contact us to get more detailed information.

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
If you're looking for backend codes, you can find it in [here](https://github.com/sparcs-kaist/zabo-server-nodejs)

- Configure the top-level `parserOptions` property like this:
## Table of Contents

```js
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
## Prerequisites

**You'll need to have Node 18.18.2 in local development and production machine**

You can use [fnm](https://github.com/Schniz/fnm). That's all you need.

```shell
$ node -v // v18.18.2
```

- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
## Getting Started

### Running Development Server

Run server
```shell
$ cp .env.example .env.development // copy config

$ vim .env.development // setup configuration

$ yarn // Installing dependencies

$ yarn dev // used vite for project configuration. yarn dev will run vite development server
```

### Running Production Server
```shell
$ // check if there is a zabo-boards package in sparcs-kaist organization
$ git clone https://github.com/sparcs-kaist/zabo-boards.git // clone repo
$ cp .env.example .env.production // copy config
$ docker compose -p zabo-boards -f .docker/docker-compose.yaml up -d // run zabo boards server

```
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"prod": "docker compose -p zabo-boards -f .docker/docker-compose.yaml --env-file .docker/.env.production",
"prod:up": "yarn prod up -d",
"prod:down": "yarn prod down",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"prettier": "prettier --write --config .prettierrc -u",
Expand All @@ -22,15 +25,17 @@
"@react-spring/web": "^9.7.3",
"@reduxjs/toolkit": "^1.9.7",
"@types/node": "^20.8.10",
"axios": "^1.5.1",
"axios": "^1.6.8",
"dayjs": "^1.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-qr-code": "^2.0.12",
"react-redux": "^8.1.3",
"react-transition-group": "^4.4.5",
"redux-thunk": "^2.4.2",
"serve": "^14.2.3",
"usehooks-ts": "^2.9.1",
"vite": "^5.2.10",
"vite-tsconfig-paths": "^4.2.1"
},
"devDependencies": {
Expand All @@ -54,7 +59,6 @@
"lint-staged": "^14.0.1",
"prettier": "3.0.3",
"sass": "^1.69.0",
"typescript": "^5.0.2",
"vite": "^4.4.5"
"typescript": "^5.0.2"
}
}
1 change: 1 addition & 0 deletions src/App.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@
.read-the-docs {
color: #888;
}

4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Board } from "@/components";
import { AuthPage } from "@/components";
import { Provider } from "react-redux";
import { store } from "@/redux/store";

const App = () => (
<Provider store={store}>
<Board />
<AuthPage />
</Provider>
);

Expand Down
46 changes: 46 additions & 0 deletions src/components/Auth/Auth.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@import "src/styles";

.modalWrapper {
display: flex;
justify-content: center;
align-items: center;
padding-top: 500px;
}

.modalContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 300px;
max-width: 1800px;
}

.modalTitle {
font-size: 100px;
}

.modalContent {
font-size: 50px;
}

.form {
display: flex;
flex-direction: column;
margin-top: 100px;
}

.input {
font-size: 50px;
margin: 10px;
}

.submit {
margin-top: 20px;
font-size: 50px;
}

.errorBox {
font-size: 50px;
color: red;
}
46 changes: 46 additions & 0 deletions src/components/Auth/Auth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { type ChangeEvent, useState } from "react";
import { useAppDispatch, useAppSelector } from "@/types";
import { type RootState } from "@/redux/store";
import { Board } from "@/components/Board";
import { loginThunk } from "@/redux/auth/loginThunk";
import { LoginPage } from "@/components/Auth/LoginPage";

export const AuthPage = () => {
const [deviceId, setDeviceId] = useState("");
const [pin, setPin] = useState("");

const isLoggedIn = useAppSelector(
(state: RootState) => state.auth.isLoggedIn,
);

const errorMessage = useAppSelector(
(state: RootState) => state.auth.errorMessage,
);

const onDeviceIdChange = (e: ChangeEvent<HTMLInputElement>) => {
setDeviceId(e.target.value);
};

const onPinChange = (e: ChangeEvent<HTMLInputElement>) => {
setPin(e.target.value);
};

const dispatch = useAppDispatch();

const onSubmitHandler = () => {
dispatch(loginThunk(deviceId, pin));
setDeviceId("");
setPin("");
};

return isLoggedIn ? (
<Board />
) : (
<LoginPage
errorMessage={errorMessage}
onDeviceIdChange={onDeviceIdChange}
onPinChange={onPinChange}
onSubmitHandler={onSubmitHandler}
/>
);
};
Loading