Skip to content

Commit 5eba0ce

Browse files
committed
Feat (CICD) : [WIP] Create CI
1 parent 67d380c commit 5eba0ce

File tree

16 files changed

+277
-28
lines changed

16 files changed

+277
-28
lines changed

.eslintrc.cjs

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ module.exports = {
1414
'warn',
1515
{ allowConstantExport: true },
1616
],
17+
'@typescript-eslint/no-explicit-any': 'off',
1718
},
1819
};

.github/workflows/DeployDocker.yml

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Docker Image CI/CD
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- develop
8+
- features/*
9+
pull_request:
10+
branches:
11+
- main
12+
- develop
13+
release:
14+
types: [published]
15+
16+
jobs:
17+
setup_tag:
18+
name: Setup dockerTag
19+
runs-on: ubuntu-latest
20+
outputs:
21+
docker_tag: ${{ steps.setup_docker_tag.outputs.DockerTag }}
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v3
25+
26+
- name: Setup dockerTag
27+
id: setup_docker_tag
28+
run: |
29+
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
30+
case "${{ github.base_ref }}" in
31+
"develop")
32+
echo "::set-output name=DockerTag::dev-pr"
33+
;;
34+
"main")
35+
echo "::set-output name=DockerTag::main-pr"
36+
;;
37+
esac
38+
else
39+
case "${{ github.ref }}" in
40+
refs/heads/features/*)
41+
echo "::set-output name=DockerTag::alpha"
42+
;;
43+
"refs/heads/develop")
44+
echo "::set-output name=DockerTag::dev"
45+
;;
46+
"refs/heads/main")
47+
echo "::set-output name=DockerTag::rc"
48+
;;
49+
"refs/tags/*")
50+
echo "::set-output name=DockerTag::release"
51+
;;
52+
esac
53+
fi
54+
55+
build_app:
56+
name: install dependencies and build
57+
runs-on: ubuntu-latest
58+
59+
steps:
60+
- name: Checkout repo
61+
uses: actions/checkout@v3
62+
63+
- name: Install Node.js
64+
uses: actions/setup-node@v3
65+
with:
66+
node-version: lts/*
67+
registry-url: https://npm.pkg.github.com/
68+
69+
- uses: pnpm/action-setup@v2
70+
name: Install pnpm
71+
with:
72+
version: latest
73+
run_install: false
74+
75+
- name: Get pnpm store directory
76+
shell: bash
77+
run: |
78+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
79+
80+
- name: Set NPM Token
81+
run: echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}">.npmrc
82+
83+
- uses: actions/cache@v3
84+
name: Setup pnpm cache
85+
with:
86+
path: ${{ env.STORE_PATH }}
87+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
88+
restore-keys: |
89+
${{ runner.os }}-pnpm-store-
90+
91+
- name: Install dependencies
92+
run: pnpm install
93+
94+
- name: Build project
95+
run: pnpm build
96+
97+
- name: Archive compiled files
98+
uses: actions/upload-artifact@v2
99+
with:
100+
name: compiled-files
101+
path: ./dist/*
102+
103+
CI:
104+
name: Building and deploy Image from-a2b-map
105+
runs-on: ubuntu-latest
106+
needs:
107+
- setup_tag
108+
- build_app
109+
steps:
110+
- name: Checkout
111+
uses: actions/checkout@v3
112+
113+
- name: Download compiled files artifact
114+
uses: actions/download-artifact@v2
115+
with:
116+
name: compiled-files
117+
path: ./dist
118+
119+
- name: DockerHub login
120+
uses: docker/login-action@v1
121+
with:
122+
username: ${{ secrets.DOCKER_USER }}
123+
password: ${{ secrets.DOCKER_PASSWORD }}
124+
125+
- name: Set up Docker Buildx
126+
uses: docker/setup-buildx-action@v1
127+
128+
- name: Build Docker Image
129+
run: docker buildx build --platform linux/amd64,linux/arm --file ./Dockerfile.Release --tag ${{ secrets.REGISTRY_NAME }}/from-a2b-map:${{ needs.setup_tag.outputs.docker_tag }} --push ./dist
130+
131+
# CD:
132+
# name: Update Portainer Service
133+
# runs-on: ubuntu-latest
134+
# needs: CI
135+
# if: ${{ needs.CI.result == 'success' }}
136+
# steps:
137+
# - name: Send POST request to Portainer webhook
138+
# run: |
139+
# case "${{ github.ref }}" in
140+
# "refs/heads/develop")
141+
# curl -X POST -H "Content-Type: application/json" -d '{}' ${{ secrets.FROMA2B_PORTAINER_WEBHOOK_API_DEV }}
142+
# ;;
143+
# "refs/heads/main")
144+
# curl -X POST -H "Content-Type: application/json" -d '{}' ${{ secrets.FROMA2B_PORTAINER_WEBHOOK_STAGING }}
145+
# ;;
146+
# "refs/tags/*")
147+
# curl -X POST -H "Content-Type: application/json" -d '{}' ${{ secrets.FROMA2B_PORTAINER_WEBHOOK_API_RELEASE }}
148+
# ;;
149+
# esac

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ pnpm-lock.yaml
3636
.env.production
3737

3838
.npmrc
39+
40+
.VSCodeCounter/

Dockerfile.Release

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM nginx:stable-alpine
2+
3+
COPY ./dist /usr/share/nginx/html
4+
5+
COPY nginx/nginx.conf /etc/nginx/conf.d
6+
7+
EXPOSE 80
8+
9+
CMD ["nginx", "-g", "daemon off;"]

nginx/nginx.conf

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
map $sent_http_content_type $expires {
2+
3+
default off;
4+
5+
text/html 15m;
6+
7+
text/css 15m;
8+
9+
application/javascript 15m;
10+
11+
~image/ 15m;
12+
13+
}
14+
15+
server {
16+
17+
listen 80;
18+
19+
root /usr/share/nginx/html;
20+
21+
index index.html;
22+
23+
etag on;
24+
25+
expires $expires;
26+
27+
location / {
28+
29+
try_files $uri @prerender;
30+
31+
}
32+
33+
location @prerender {
34+
35+
proxy_set_header X-Prerender-Token GsMLRmorzgxywljuDowD;
36+
37+
38+
set $prerender 0;
39+
40+
if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest\/0.|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp|Screaming Frog SEO Spider") {
41+
42+
set $prerender 1;
43+
44+
}
45+
46+
if ($args ~ "escaped_fragment") {
47+
48+
set $prerender 1;
49+
50+
}
51+
52+
if ($http_user_agent ~ "Prerender") {
53+
54+
set $prerender 0;
55+
56+
}
57+
58+
if ($uri ~* ".(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
59+
60+
set $prerender 0;
61+
62+
}
63+
64+
65+
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
66+
67+
resolver 8.8.8.8;
68+
69+
70+
if ($prerender = 1) {
71+
72+
73+
#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
74+
75+
set $prerender "service.prerender.io";
76+
77+
rewrite .* /$scheme://$host$request_uri? break;
78+
79+
proxy_pass http://$prerender;
80+
81+
}
82+
83+
if ($prerender = 0) {
84+
85+
rewrite .* /index.html break;
86+
87+
}
88+
89+
}
90+
91+
error_page 500 502 503 504 /50x.html;
92+
93+
location = /50x.html {
94+
95+
root /usr/share/nginx/html;
96+
97+
}
98+
99+
}

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"dev": "vite --host",
88
"start": "pnpm i && docker compose up --build -d",
99
"build": "tsc && vite build",
10-
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives",
1111
"preview": "vite preview",
1212
"updateClientApiLatest": "pnpm update @FullStackMap/from-a2b@latest",
1313
"updateClientApi": "pnpm update @FullStackMap/from-a2b"

src/assets/header-backgroud.png

1.21 MB
Loading

src/assets/vite.svg

+1
Loading

src/components/header/DefaultHeader.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const DefaultHeader = (props: DefaultHeaderProps) => {
6666
/>
6767
<Group>
6868
<Group visibleFrom="sm">
69-
{isLogged && (
69+
{isLogged() && (
7070
<>
7171
<Button
7272
leftSection={<IconSquareRoundedPlus size={20} />}

src/components/starComponent/StarLikeComponent.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export type StarLikeComponentProps = {
77

88
export const StarLikeComponent = (props: StarLikeComponentProps) => {
99
const updateRating = (e: FormEvent<HTMLFormElement>) => {
10-
props.ChangeRating(e.target.value);
10+
props.ChangeRating((e.target as any).value);
1111
};
1212

1313
const ratings = [

src/hooks/useQueryParams.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
export const useQueryParams = (url: string | null = null) => {
22
const paramsObj = new URLSearchParams(url ? url : window.location.search);
3-
const newObj = {};
3+
const newObj: { [key: string]: string } = {};
44
for (const [key, value] of paramsObj) {
55
newObj[key] = value;
66
}
7-
return newObj as unknown;
7+
return newObj;
88
};

src/layout/header/HomeLayout.tsx

+1-16
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,9 @@ import {
1010
} from '@mantine/core';
1111
import { useDisclosure } from '@mantine/hooks';
1212
import { Outlet } from 'react-router-dom';
13-
import { LoginDto } from '../../Models/Auth/LoginDto';
14-
import { useAuthStore } from '../../store/useAuthStore';
1513
import classes from './HeaderMegaMenu.module.css';
1614

1715
const HomeLayout = () => {
18-
const authStore = useAuthStore();
19-
20-
const handleClickLogin: () => Promise<void> = async () => {
21-
const loginDto: LoginDto = {
22-
Username: 'Dercraker',
23-
Password: 'NMdRx$HqyT8jX6',
24-
};
25-
26-
authStore.login(loginDto);
27-
};
28-
2916
const [drawerOpened, { toggle: toggleDrawer, close: closeDrawer }] =
3017
useDisclosure(false);
3118
return (
@@ -47,9 +34,7 @@ const HomeLayout = () => {
4734
</Group>
4835

4936
<Group visibleFrom="sm">
50-
<Button variant="default" onClick={handleClickLogin}>
51-
Se connecter
52-
</Button>
37+
<Button variant="default">Se connecter</Button>
5338
</Group>
5439

5540
<Burger

src/pages/forgotPassword/ForgotPasswordPage.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable @typescript-eslint/no-explicit-any */
21
import { ResetPasswordDto } from '@FullStackMap/from-a2b';
32
import { Button, PasswordInput, Title } from '@mantine/core';
43
import { useForm } from '@mantine/form';
@@ -17,7 +16,7 @@ export const ForgotPasswordPage = () => {
1716
const { ErrorNotify, SuccessNotify } = useNotify();
1817
useEffect(() => {
1918
if (!queryParams.Token || !queryParams.Email) navigate('/');
20-
}, [queryParams]);
19+
}, [queryParams, navigate]);
2120

2221
const resetPasswordSchema = z
2322
.object({

src/pages/login/LoginPage.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable @typescript-eslint/no-explicit-any */
21
import { LoginDto } from '@FullStackMap/from-a2b';
32
import {
43
Anchor,
@@ -27,7 +26,7 @@ export function LoginPage() {
2726
const login = useAuthStore((s: AuthStore) => s.login);
2827
const navigate = useNavigate();
2928

30-
const { ErrorNotify } = useNotify();
29+
const { ErrorNotify, SuccessNotify } = useNotify();
3130

3231
const [
3332
resetPasswordRequestModalIsOpen,
@@ -59,6 +58,12 @@ export function LoginPage() {
5958
message: 'Votre mot de passe ou identifiant sont incorrect!',
6059
} as NotifyDto);
6160
}),
61+
onSuccess: () => {
62+
SuccessNotify({
63+
title: 'Connexion réussie',
64+
message: 'Vous êtes maintenant connecté!',
65+
} as NotifyDto);
66+
},
6267
});
6368

6469
useEffect(() => {

0 commit comments

Comments
 (0)