ci: add CI/CD FTP deployment workflows and local deploy script for Hostverge
This commit is contained in:
40
.forgejo/workflows/deploy.yml
Normal file
40
.forgejo/workflows/deploy.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: Build & Deploy to Hostverge FTP
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 📥 Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 🟢 Setup Node.js 20
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: 📦 Install dependencies
|
||||||
|
run: npm ci || npm install
|
||||||
|
|
||||||
|
- name: 🛠️ Build application
|
||||||
|
env:
|
||||||
|
VITE_NCB_INSTANCE: ${{ secrets.VITE_NCB_INSTANCE || '54770_uwu_finances' }}
|
||||||
|
VITE_NCB_SECRET_KEY: ${{ secrets.VITE_NCB_SECRET_KEY || 'sk_live_0dydoaq1kib4f23ou6' }}
|
||||||
|
VITE_NCB_DATA_API_URL: ${{ secrets.VITE_NCB_DATA_API_URL || 'https://eu-api.nocodebackend.com' }}
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: 🚀 Sync files to Hostverge via FTP
|
||||||
|
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
||||||
|
with:
|
||||||
|
server: ${{ secrets.FTP_SERVER || 'ka-el.fr' }}
|
||||||
|
username: ${{ secrets.FTP_USERNAME || 'antigravity@ka-el.fr' }}
|
||||||
|
password: ${{ secrets.FTP_PASSWORD || 'dxr1yaor4i' }}
|
||||||
|
local-dir: ./dist/
|
||||||
|
server-dir: ./
|
||||||
|
dangerous-clean-slate: false
|
||||||
40
.gitea/workflows/deploy.yml
Normal file
40
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: Build & Deploy to Hostverge FTP
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 📥 Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 🟢 Setup Node.js 20
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
|
- name: 📦 Install dependencies
|
||||||
|
run: npm ci || npm install
|
||||||
|
|
||||||
|
- name: 🛠️ Build application
|
||||||
|
env:
|
||||||
|
VITE_NCB_INSTANCE: ${{ secrets.VITE_NCB_INSTANCE || '54770_uwu_finances' }}
|
||||||
|
VITE_NCB_SECRET_KEY: ${{ secrets.VITE_NCB_SECRET_KEY || 'sk_live_0dydoaq1kib4f23ou6' }}
|
||||||
|
VITE_NCB_DATA_API_URL: ${{ secrets.VITE_NCB_DATA_API_URL || 'https://eu-api.nocodebackend.com' }}
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: 🚀 Sync files to Hostverge via FTP
|
||||||
|
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
||||||
|
with:
|
||||||
|
server: ${{ secrets.FTP_SERVER || 'ka-el.fr' }}
|
||||||
|
username: ${{ secrets.FTP_USERNAME || 'antigravity@ka-el.fr' }}
|
||||||
|
password: ${{ secrets.FTP_PASSWORD || 'dxr1yaor4i' }}
|
||||||
|
local-dir: ./dist/
|
||||||
|
server-dir: ./
|
||||||
|
dangerous-clean-slate: false
|
||||||
41
.github/workflows/deploy.yml
vendored
Normal file
41
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
name: Build & Deploy to Hostverge FTP
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 📥 Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 🟢 Setup Node.js 20
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: 📦 Install dependencies
|
||||||
|
run: npm ci || npm install
|
||||||
|
|
||||||
|
- name: 🛠️ Build application
|
||||||
|
env:
|
||||||
|
VITE_NCB_INSTANCE: ${{ secrets.VITE_NCB_INSTANCE || '54770_uwu_finances' }}
|
||||||
|
VITE_NCB_SECRET_KEY: ${{ secrets.VITE_NCB_SECRET_KEY || 'sk_live_0dydoaq1kib4f23ou6' }}
|
||||||
|
VITE_NCB_DATA_API_URL: ${{ secrets.VITE_NCB_DATA_API_URL || 'https://eu-api.nocodebackend.com' }}
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: 🚀 Sync files to Hostverge via FTP
|
||||||
|
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
||||||
|
with:
|
||||||
|
server: ${{ secrets.FTP_SERVER || 'ka-el.fr' }}
|
||||||
|
username: ${{ secrets.FTP_USERNAME || 'antigravity@ka-el.fr' }}
|
||||||
|
password: ${{ secrets.FTP_PASSWORD || 'dxr1yaor4i' }}
|
||||||
|
local-dir: ./dist/
|
||||||
|
server-dir: ./
|
||||||
|
dangerous-clean-slate: false
|
||||||
34
.gitlab-ci.yml
Normal file
34
.gitlab-ci.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
image: node:20
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
build_app:
|
||||||
|
stage: build
|
||||||
|
variables:
|
||||||
|
VITE_NCB_INSTANCE: "54770_uwu_finances"
|
||||||
|
VITE_NCB_SECRET_KEY: "sk_live_0dydoaq1kib4f23ou6"
|
||||||
|
VITE_NCB_DATA_API_URL: "https://eu-api.nocodebackend.com"
|
||||||
|
script:
|
||||||
|
- npm ci || npm install
|
||||||
|
- npm run build
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- dist/
|
||||||
|
expire_in: 1 hour
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
|
||||||
|
deploy_ftp:
|
||||||
|
stage: deploy
|
||||||
|
dependencies:
|
||||||
|
- build_app
|
||||||
|
before_script:
|
||||||
|
- apt-get update -qq && apt-get install -y -qq lftp
|
||||||
|
script:
|
||||||
|
- lftp -e "set ftp:ssl-allow no; open ka-el.fr; user antigravity@ka-el.fr dxr1yaor4i; mirror -R dist/ /; quit"
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -26,6 +26,8 @@
|
|||||||
"@types/react-dom": "^19.2.7",
|
"@types/react-dom": "^19.2.7",
|
||||||
"@vitejs/plugin-react": "^6.1.1",
|
"@vitejs/plugin-react": "^6.1.1",
|
||||||
"autoprefixer": "^10.6.1",
|
"autoprefixer": "^10.6.1",
|
||||||
|
"basic-ftp": "^6.2.1",
|
||||||
|
"dotenv": "^18.0.4",
|
||||||
"oxlint": "^1.81.0",
|
"oxlint": "^1.81.0",
|
||||||
"postcss": "^8.5.28",
|
"postcss": "^8.5.28",
|
||||||
"tailwindcss": "^4.3.3",
|
"tailwindcss": "^4.3.3",
|
||||||
@@ -1394,6 +1396,16 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/basic-ftp": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-bK67isD+lKq46AU8vNtjvMaT2ZqAOAmNCbxUHlFBRD4k15NWxyEjmaKtZPlgce58So4BNTjITGQOVTjL9y0ECA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.29.1",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.1.tgz",
|
||||||
@@ -1611,6 +1623,22 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "18.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-18.0.4.tgz",
|
||||||
|
"integrity": "sha512-jGt9uI5BIxpVO15kvy+iEFqNAwxYClKWnkptLjSNPnFLC003Imd0ofr3aEVsbpHdSBdSsbcApNIlz4nbyGMwdA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"bin": {
|
||||||
|
"dotenv": "dist/index.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://dotenvx.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.439",
|
"version": "1.5.439",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.439.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.439.tgz",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc -b && vite build",
|
"build": "tsc -b && vite build",
|
||||||
|
"deploy": "node scripts/deploy-ftp.cjs",
|
||||||
"lint": "oxlint",
|
"lint": "oxlint",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
@@ -28,6 +29,8 @@
|
|||||||
"@types/react-dom": "^19.2.7",
|
"@types/react-dom": "^19.2.7",
|
||||||
"@vitejs/plugin-react": "^6.1.1",
|
"@vitejs/plugin-react": "^6.1.1",
|
||||||
"autoprefixer": "^10.6.1",
|
"autoprefixer": "^10.6.1",
|
||||||
|
"basic-ftp": "^6.2.1",
|
||||||
|
"dotenv": "^18.0.4",
|
||||||
"oxlint": "^1.81.0",
|
"oxlint": "^1.81.0",
|
||||||
"postcss": "^8.5.28",
|
"postcss": "^8.5.28",
|
||||||
"tailwindcss": "^4.3.3",
|
"tailwindcss": "^4.3.3",
|
||||||
|
|||||||
49
scripts/deploy-ftp.cjs
Normal file
49
scripts/deploy-ftp.cjs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const ftp = require('basic-ftp');
|
||||||
|
const path = require('path');
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
async function deploy() {
|
||||||
|
const client = new ftp.Client();
|
||||||
|
client.ftp.verbose = true;
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
host: process.env.FTP_HOST || 'ka-el.fr',
|
||||||
|
user: process.env.FTP_USER || 'antigravity@ka-el.fr',
|
||||||
|
password: process.env.FTP_PASSWORD || 'dxr1yaor4i',
|
||||||
|
port: parseInt(process.env.FTP_PORT || '21', 10),
|
||||||
|
secure: false, // Set to true or 'implicit' if FTPS is enforced
|
||||||
|
};
|
||||||
|
|
||||||
|
const localDistDir = path.join(__dirname, '..', 'dist');
|
||||||
|
const remoteTargetDir = process.env.FTP_REMOTE_DIR || '/';
|
||||||
|
|
||||||
|
console.log(`\n🚀 [Hostverge FTP Deploy] Connecting to ${config.host} as ${config.user}...`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.access({
|
||||||
|
host: config.host,
|
||||||
|
user: config.user,
|
||||||
|
password: config.password,
|
||||||
|
port: config.port,
|
||||||
|
secure: config.secure,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`✅ [FTP Connected] Uploading files from "${localDistDir}" to remote "${remoteTargetDir}"...`);
|
||||||
|
|
||||||
|
// Ensure remote directory exists and upload full dist/ content
|
||||||
|
await client.ensureDir(remoteTargetDir);
|
||||||
|
await client.clearWorkingDir();
|
||||||
|
await client.uploadFromDir(localDistDir);
|
||||||
|
|
||||||
|
console.log(`\n🎉 [Success] Application successfully deployed to Hostverge (${config.host}) !\n`);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`\n❌ [FTP Deploy Failed]:`, err);
|
||||||
|
process.exit(1);
|
||||||
|
} finally {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy();
|
||||||
Reference in New Issue
Block a user