fix(ci-cd): add github workflows
This commit is contained in:
137
.github/workflows/main.yaml
vendored
Normal file
137
.github/workflows/main.yaml
vendored
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
name: Build and deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Notify Telegram start building
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
to: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
|
message: |
|
||||||
|
🚀 Запуск сборки!
|
||||||
|
Сервер: ${{ secrets.SERVER_NAME }}
|
||||||
|
Репозиторий: ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: smallbuster/ocenka-web:latest
|
||||||
|
build-args: |
|
||||||
|
NEXT_PUBLIC_MAIL_USER=${{ secrets.NEXT_PUBLIC_MAIL_USER }}
|
||||||
|
NEXT_PUBLIC_MAIL_PASS=${{ secrets.NEXT_PUBLIC_MAIL_PASS }}
|
||||||
|
NEXT_PUBLIC_MAIL_FROM=${{ secrets.NEXT_PUBLIC_MAIL_FROM }}
|
||||||
|
NEXT_PUBLIC_MAIL_TO=${{ secrets.NEXT_PUBLIC_MAIL_TO }}
|
||||||
|
NEXT_PUBLIC_MAIL_SECURE_KEY=${{ secrets.NEXT_PUBLIC_MAIL_SECURE_KEY }}
|
||||||
|
|
||||||
|
- name: Notify Telegram about success
|
||||||
|
if: success()
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
to: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
|
message: |
|
||||||
|
✅ Сборка успешно завершена!
|
||||||
|
Сервер: ${{ secrets.SERVER_NAME }}
|
||||||
|
Репозиторий: ${{ github.repository }}
|
||||||
|
Ветка: ${{ github.ref_name }}
|
||||||
|
Коммит: ${{ github.sha }}
|
||||||
|
|
||||||
|
- name: Notify Telegram about failure
|
||||||
|
if: failure()
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
to: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
|
message: |
|
||||||
|
❌ Сборка проекта неудачна!
|
||||||
|
Сервер: ${{ secrets.SERVER_NAME }}
|
||||||
|
Репозиторий: ${{ github.repository }}
|
||||||
|
Ветка: ${{ github.ref_name }}
|
||||||
|
Коммит: ${{ github.sha }}
|
||||||
|
Подробности: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
runs-on: self-hosted
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- name: Notify Telegram start deploy
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
to: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
|
message: |
|
||||||
|
🐳 Запуск деплоя!
|
||||||
|
Сервер: ${{ secrets.SERVER_NAME }}
|
||||||
|
Репозиторий: ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up Docker Compose
|
||||||
|
run: |
|
||||||
|
docker compose version
|
||||||
|
|
||||||
|
- name: Stop and remove existing containers
|
||||||
|
run: |
|
||||||
|
docker compose -f docker-compose.yaml down || true
|
||||||
|
|
||||||
|
- name: Pull Docker images
|
||||||
|
run: |
|
||||||
|
docker compose -f docker-compose.yaml pull
|
||||||
|
|
||||||
|
- name: Start containers
|
||||||
|
run: |
|
||||||
|
docker compose -f docker-compose.yaml up -d
|
||||||
|
|
||||||
|
- name: Notify Telegram about success
|
||||||
|
if: success()
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
to: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
|
message: |
|
||||||
|
✅ Деплой успешно завершен!
|
||||||
|
Сервер: ${{ secrets.SERVER_NAME }}
|
||||||
|
Репозиторий: ${{ github.repository }}
|
||||||
|
Ветка: ${{ github.ref_name }}
|
||||||
|
Коммит: ${{ github.sha }}
|
||||||
|
|
||||||
|
- name: Notify Telegram about failure
|
||||||
|
if: failure()
|
||||||
|
uses: appleboy/telegram-action@master
|
||||||
|
with:
|
||||||
|
to: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
|
message: |
|
||||||
|
❌ Деплой не удался!
|
||||||
|
Сервер: ${{ secrets.SERVER_NAME }}
|
||||||
|
Репозиторий: ${{ github.repository }}
|
||||||
|
Ветка: ${{ github.ref_name }}
|
||||||
|
Коммит: ${{ github.sha }}
|
||||||
|
Подробности: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||||
6
.idea/compiler.xml
generated
Normal file
6
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="TypeScriptCompiler">
|
||||||
|
<option name="useServicePoweredTypesWasEnabledByExperiment" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
82
.idea/workspace.xml
generated
82
.idea/workspace.xml
generated
@@ -5,26 +5,10 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="2a96f817-9dc2-4f3c-893a-c4974c750774" name="Changes" comment="">
|
<list default="true" id="2a96f817-9dc2-4f3c-893a-c4974c750774" name="Changes" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/.github/workflows/main.yaml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/.idea/compiler.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/api/og-image/lib/render.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/Dockerfile" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/api/og-image/lib/template.tsx" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/api/og-image/lib/types.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/api/og-image/route.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/api/og/route.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/api/og/route.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/contacts/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/contacts/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/cookies/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/cookies/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/borodin-vitalij-petrovich/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/borodin-vitalij-petrovich/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/gjulmamedov-javar-firmamed-ogly/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/gjulmamedov-javar-firmamed-ogly/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/jancen-jana-nikolaevna/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/jancen-jana-nikolaevna/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/kaminskij-dmitrij-olegovich/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/kaminskij-dmitrij-olegovich/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/kolodij-aleksandr-sergeevich/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/kolodij-aleksandr-sergeevich/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/mikova-inna-georgievna/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/mikova-inna-georgievna/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/mitjaev-aleksej-aleksandrovich/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/mitjaev-aleksej-aleksandrovich/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/polinov-andrej-vladimirovich/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/polinov-andrej-vladimirovich/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/experts/volkova-goncharova-tatjana-anatolevna/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/experts/volkova-goncharova-tatjana-anatolevna/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/privacy-policy/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/privacy-policy/page.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/user-agreement/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/user-agreement/page.tsx" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -32,7 +16,7 @@
|
|||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="DarkyenusTimeTracker">
|
<component name="DarkyenusTimeTracker">
|
||||||
<option name="totalTimeSeconds" value="223885" />
|
<option name="totalTimeSeconds" value="225852" />
|
||||||
<option name="gitIntegration" value="true" />
|
<option name="gitIntegration" value="true" />
|
||||||
<option name="naggedAbout" value="1" />
|
<option name="naggedAbout" value="1" />
|
||||||
</component>
|
</component>
|
||||||
@@ -60,32 +44,35 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"git-widget-placeholder": "dev",
|
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||||
"ignore.virus.scanning.warn.message": "true",
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"js.debugger.nextJs.config.created.client": "true",
|
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
||||||
"js.debugger.nextJs.config.created.server": "true",
|
"git-widget-placeholder": "dev",
|
||||||
"junie.onboarding.icon.badge.shown": "true",
|
"ignore.virus.scanning.warn.message": "true",
|
||||||
"list.type.of.created.stylesheet": "SCSS",
|
"js.debugger.nextJs.config.created.client": "true",
|
||||||
"node.js.detected.package.eslint": "true",
|
"js.debugger.nextJs.config.created.server": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"junie.onboarding.icon.badge.shown": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"list.type.of.created.stylesheet": "SCSS",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.detected.package.eslint": "true",
|
||||||
"nodejs_package_manager_path": "npm",
|
"node.js.detected.package.tslint": "true",
|
||||||
"npm.Next.js: server-side.executor": "Run",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"prettierjs.PrettierConfiguration.Package": "C:\\dev-personal\\ocenka-web\\node_modules\\prettier",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"settings.editor.selected.configurable": "terminal",
|
"nodejs_package_manager_path": "npm",
|
||||||
"to.speed.mode.migration.done": "true",
|
"npm.Next.js: server-side.executor": "Run",
|
||||||
"ts.external.directory.path": "C:\\dev-personal\\ocenka-web\\node_modules\\typescript\\lib",
|
"prettierjs.PrettierConfiguration.Package": "C:\\dev-personal\\ocenka-web\\node_modules\\prettier",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"settings.editor.selected.configurable": "terminal",
|
||||||
|
"to.speed.mode.migration.done": "true",
|
||||||
|
"ts.external.directory.path": "C:\\dev-personal\\ocenka-web\\node_modules\\typescript\\lib",
|
||||||
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="C:\dev-personal\ocenka-web\public\images" />
|
<recent name="C:\dev-personal\ocenka-web\public\images" />
|
||||||
@@ -112,7 +99,7 @@
|
|||||||
<component name="SharedIndexes">
|
<component name="SharedIndexes">
|
||||||
<attachedChunks>
|
<attachedChunks>
|
||||||
<set>
|
<set>
|
||||||
<option value="bundled-js-predefined-d6986cc7102b-a71380e98a7c-JavaScript-WS-252.28238.10" />
|
<option value="bundled-js-predefined-d6986cc7102b-c7e53b3be11b-JavaScript-WS-253.28294.332" />
|
||||||
</set>
|
</set>
|
||||||
</attachedChunks>
|
</attachedChunks>
|
||||||
</component>
|
</component>
|
||||||
@@ -132,7 +119,8 @@
|
|||||||
<workItem from="1764825390464" duration="26961000" />
|
<workItem from="1764825390464" duration="26961000" />
|
||||||
<workItem from="1765196288370" duration="332000" />
|
<workItem from="1765196288370" duration="332000" />
|
||||||
<workItem from="1765196704782" duration="4455000" />
|
<workItem from="1765196704782" duration="4455000" />
|
||||||
<workItem from="1765279298291" duration="3352000" />
|
<workItem from="1765279298291" duration="3813000" />
|
||||||
|
<workItem from="1765435962765" duration="3601000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
20
Dockerfile
20
Dockerfile
@@ -13,6 +13,19 @@ RUN npm install --frozen-lockfile
|
|||||||
# Копируем все файлы проекта
|
# Копируем все файлы проекта
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
# Аргумент сборки для переменной окружения
|
||||||
|
ARG NEXT_PUBLIC_MAIL_USER
|
||||||
|
ARG NEXT_PUBLIC_MAIL_PASS
|
||||||
|
ARG NEXT_PUBLIC_MAIL_FROM
|
||||||
|
ARG NEXT_PUBLIC_MAIL_TO
|
||||||
|
ARG NEXT_PUBLIC_MAIL_SECURE_KEY
|
||||||
|
|
||||||
|
ENV NEXT_PUBLIC_MAIL_USER=$NEXT_PUBLIC_MAIL_USER \
|
||||||
|
NEXT_PUBLIC_MAIL_PASS=$NEXT_PUBLIC_MAIL_PASS \
|
||||||
|
NEXT_PUBLIC_MAIL_FROM=$NEXT_PUBLIC_MAIL_FROM \
|
||||||
|
NEXT_PUBLIC_MAIL_TO=$NEXT_PUBLIC_MAIL_TO \
|
||||||
|
NEXT_PUBLIC_MAIL_SECURE_KEY=$NEXT_PUBLIC_MAIL_SECURE_KEY
|
||||||
|
|
||||||
# Собираем приложение
|
# Собираем приложение
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
@@ -21,7 +34,12 @@ FROM node:22-alpine AS runner
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ENV NODE_ENV=production \
|
ENV NODE_ENV=production \
|
||||||
NEXT_TELEMETRY_DISABLED=1
|
NEXT_TELEMETRY_DISABLED=1 \
|
||||||
|
NEXT_PUBLIC_MAIL_USER=$NEXT_PUBLIC_MAIL_USER \
|
||||||
|
NEXT_PUBLIC_MAIL_PASS=$NEXT_PUBLIC_MAIL_PASS \
|
||||||
|
NEXT_PUBLIC_MAIL_FROM=$NEXT_PUBLIC_MAIL_FROM \
|
||||||
|
NEXT_PUBLIC_MAIL_TO=$NEXT_PUBLIC_MAIL_TO \
|
||||||
|
NEXT_PUBLIC_MAIL_SECURE_KEY=$NEXT_PUBLIC_MAIL_SECURE_KEY
|
||||||
|
|
||||||
# Включаем node пользователя
|
# Включаем node пользователя
|
||||||
RUN addgroup -g 1001 -S nodejs
|
RUN addgroup -g 1001 -S nodejs
|
||||||
|
|||||||
Reference in New Issue
Block a user