Skip to content

Commit

Permalink
Оптимизация механизмов обновления
Browse files Browse the repository at this point in the history
  • Loading branch information
efiand committed Feb 22, 2025
1 parent 0a9c26b commit 070c349
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 12 deletions.
18 changes: 6 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,6 @@ jobs:
- name: Build
if: "!contains(github.event.head_commit.message, '[skip-build')"
run: npm run build
- name: Prepare server
if: "!contains(github.event.head_commit.message, '[skip-build')"
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.DEPLOY_SERVER_HOST }}
username: ${{ secrets.DEPLOY_SERVER_USERNAME }}
password: ${{ secrets.DEPLOY_SERVER_PASSWORD }}
script: |
cd ${{ secrets.DEPLOY_SERVER_TARGET }}
systemctl stop cookbook
rm -rf .output
- name: Copy to server
if: "!contains(github.event.head_commit.message, '[skip-build')"
uses: appleboy/scp-action@master
Expand All @@ -42,12 +31,17 @@ jobs:
password: ${{ secrets.DEPLOY_SERVER_PASSWORD }}
source: .output/*
target: ${{ secrets.DEPLOY_SERVER_TARGET }}
- name: Finalize server
- name: Modify server
if: "!contains(github.event.head_commit.message, '[skip-build')"
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.DEPLOY_SERVER_HOST }}
username: ${{ secrets.DEPLOY_SERVER_USERNAME }}
password: ${{ secrets.DEPLOY_SERVER_PASSWORD }}
script: |
cd ${{ secrets.DEPLOY_SERVER_TARGET }}
systemctl stop cookbook
mv server server-old
mv .output server
systemctl start cookbook
rm -rf server-old
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"add-staged": "git add .",
"build": "nuxt typecheck && nuxt build",
"dev": "nuxt dev",
"dump": "node tools/dump",
"eslint": "eslint . --ext .vue,.js,.cjs,.ts --ignore-path .gitignore --fix --quiet",
"lint": "nuxt typecheck && npm run eslint && npm run stylelint",
"postinstall": "prisma generate && nuxt prepare",
Expand Down
117 changes: 117 additions & 0 deletions tools/dump.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { createRequire } from 'module';

const require = createRequire(import.meta.url);
const { PrismaClient } = require('@prisma/client');

const YADISK_API = 'https://cloud-api.yandex.net/v1/disk/resources/upload';
const TAIL = 'overwrite=true&fields=href';
const { YADISK_TOKEN = '' } = process.env;
const SQL_PREPEND = `DELETE FROM \`recipesCategories\`;
DELETE FROM \`categories\`;
DELETE FROM \`recipes\`;
UPDATE \`structures\` SET \`parentId\` = null;
DELETE FROM \`structures\`;\n`;
const SQL_TABLES = [
'structures',
'categories',
'recipes',
'images',
'recipesCategories',
];

const prisma = new PrismaClient();

dump();

function createDump([
tableName,
rows,
]) {
if (!rows.length) {
return '';
}
const values = rows
.map(function (row) {
return Object.values(row).map(stringifyCell)
.join(', ');
})
.join('),\n(');
const columns = Object.keys(rows[0]).join('`, `');

return `INSERT INTO \`${tableName}\` (\`${columns}\`) VALUES\n(${values});`;
}

async function dump() {
const entities = await Promise.all([
prisma.structures.findMany({ orderBy: { id: 'asc' } }),
prisma.categories.findMany({ orderBy: { id: 'asc' } }),
prisma.recipes.findMany({ orderBy: { id: 'asc' } }),
prisma.images.findMany({ orderBy: { id: 'asc' } }),
prisma.recipesCategories.findMany({ orderBy: { id: 'asc' } }),
]);

const dumpedEntities = entities
.map(function (entity, i) {
return createDump([
SQL_TABLES[i],
entity,
]);
})
.filter(Boolean);
const dataJson = entities.reduce(function (acc, entity, i) {
return {
...acc,
[SQL_TABLES[i]]: entity,
};
}, {});

const filename = `dump/${Date.now()}`;

await Promise.all([
upload(`${filename}.json`, JSON.stringify(dataJson)),
upload(
`${filename}.sql`,
`${SQL_PREPEND}\n${dumpedEntities.join('\n\n')}`,
),
]);
}

function stringifyCell(value) {
if (value === null) {
return 'null';
}

if (typeof value === 'string') {
// Особенности одинарных кавычек в SQL
const safeValue = value.trim()
.replace(/(?<apos>')/gu, '$<apos>$<apos>');

return `'${safeValue}'`;
}

if (value instanceof Date) {
const data = value.toISOString().replace('T', ' ')
.slice(0, -1);

return `'${data}'`;
}

if (value instanceof Buffer) {
return value.toString();
}

return `${value}`;
}

async function upload(filename, payload) {
const response = await fetch(
`${YADISK_API}?path=app:/cookbook/${filename}&${TAIL}`,
{ headers: { Authorization: `OAuth ${YADISK_TOKEN}` } },
);
const url = (await response.json()).href.toString();

return await fetch(url, {
body: Buffer.from(payload),
method: 'PUT',
});
}

0 comments on commit 070c349

Please sign in to comment.