@kaikybrofc/omnizap-system 2.1.8 → 2.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +13 -0
- package/README.md +10 -1
- package/package.json +1 -1
- package/scripts/github-release-notify.mjs +180 -0
- package/scripts/release.sh +63 -0
package/.env.example
CHANGED
|
@@ -532,3 +532,16 @@ RELEASE_GIT_BRANCH=
|
|
|
532
532
|
RELEASE_GIT_PRE_COMMIT_MESSAGE=chore(release): auto-commit before release
|
|
533
533
|
RELEASE_GIT_COMMIT_VERSION=1
|
|
534
534
|
RELEASE_GIT_VERSION_COMMIT_PREFIX=chore(release): v
|
|
535
|
+
|
|
536
|
+
# Cria/atualiza GitHub Release (aba Releases) automaticamente no npm run release
|
|
537
|
+
RELEASE_GITHUB_RELEASE=1
|
|
538
|
+
RELEASE_GITHUB_REPO=kaikybrofc/omnizap-system
|
|
539
|
+
RELEASE_GITHUB_TOKEN=
|
|
540
|
+
RELEASE_GITHUB_TAG_PREFIX=v
|
|
541
|
+
RELEASE_GITHUB_NAME_PREFIX=v
|
|
542
|
+
RELEASE_GITHUB_GENERATE_NOTES=1
|
|
543
|
+
# Opcional: 1 para prerelease, 0 para release normal, vazio = auto (detecta '-' na versao)
|
|
544
|
+
RELEASE_GITHUB_PRERELEASE=
|
|
545
|
+
RELEASE_GITHUB_DRAFT=0
|
|
546
|
+
# Opcional: commit/tag alvo (vazio usa HEAD atual)
|
|
547
|
+
RELEASE_GITHUB_TARGET=
|
package/README.md
CHANGED
|
@@ -132,7 +132,7 @@ Variáveis legadas foram mantidas por compatibilidade (`QUOTE_API_URL`, `WAIFU_A
|
|
|
132
132
|
- `npm run pm2:prod`: sobe com PM2 usando `ecosystem.prod.config.cjs`.
|
|
133
133
|
- `npm run deploy`: deploy automático de `public/` com cache-bust, backup, validação e reload do Nginx.
|
|
134
134
|
- `npm run deploy:dry-run`: simula o deploy sem publicar/recarregar serviços.
|
|
135
|
-
- `npm run release`: bump de versão `patch` + deploy + publish
|
|
135
|
+
- `npm run release`: bump de versão `patch` + deploy + publish + atualização da aba GitHub Releases.
|
|
136
136
|
- `npm run release:minor`: bump `minor` + deploy + publish do package.
|
|
137
137
|
- `npm run release:major`: bump `major` + deploy + publish do package.
|
|
138
138
|
- `npm run test`: executa testes Node (`node --test`).
|
|
@@ -235,6 +235,15 @@ Variáveis do fluxo de release (git):
|
|
|
235
235
|
- `RELEASE_GIT_PRE_COMMIT_MESSAGE` (default: `chore(release): auto-commit before release`)
|
|
236
236
|
- `RELEASE_GIT_COMMIT_VERSION` (default: `1`) - commita alteração da versão após sucesso
|
|
237
237
|
- `RELEASE_GIT_VERSION_COMMIT_PREFIX` (default: `chore(release): v`)
|
|
238
|
+
- `RELEASE_GITHUB_RELEASE` (default: `1`) - cria/atualiza GitHub Release na aba Releases
|
|
239
|
+
- `RELEASE_GITHUB_REPO` (opcional; ex.: `kaikybrofc/omnizap-system`)
|
|
240
|
+
- `RELEASE_GITHUB_TOKEN` (opcional; fallback: `DEPLOY_GITHUB_TOKEN`/`GITHUB_TOKEN`/`GH_TOKEN`)
|
|
241
|
+
- `RELEASE_GITHUB_TAG_PREFIX` (default: `v`) - prefixo da tag (`v2.1.9`)
|
|
242
|
+
- `RELEASE_GITHUB_NAME_PREFIX` (default: `v`) - prefixo do nome exibido na release
|
|
243
|
+
- `RELEASE_GITHUB_GENERATE_NOTES` (default: `1`) - usa notas automáticas do GitHub
|
|
244
|
+
- `RELEASE_GITHUB_PRERELEASE` (default: auto) - vazio detecta `-` na versão como prerelease
|
|
245
|
+
- `RELEASE_GITHUB_DRAFT` (default: `0`)
|
|
246
|
+
- `RELEASE_GITHUB_TARGET` (opcional; vazio usa `HEAD`)
|
|
238
247
|
|
|
239
248
|
## Execução com PM2
|
|
240
249
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import dotenv from 'dotenv';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
const projectRoot = path.resolve(__dirname, '..');
|
|
12
|
+
|
|
13
|
+
dotenv.config({ path: path.join(projectRoot, '.env') });
|
|
14
|
+
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
const action = String(args[0] || '').trim();
|
|
17
|
+
|
|
18
|
+
const getArg = (flag, fallback = '') => {
|
|
19
|
+
const index = args.indexOf(flag);
|
|
20
|
+
if (index === -1) return fallback;
|
|
21
|
+
return String(args[index + 1] || fallback).trim();
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const env = (...keys) => {
|
|
25
|
+
for (const key of keys) {
|
|
26
|
+
const value = process.env[key];
|
|
27
|
+
if (value && String(value).trim()) return String(value).trim();
|
|
28
|
+
}
|
|
29
|
+
return '';
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const toBool = (value, fallback = false) => {
|
|
33
|
+
if (value === undefined || value === null || value === '') return fallback;
|
|
34
|
+
const normalized = String(value).trim().toLowerCase();
|
|
35
|
+
return ['1', 'true', 'yes', 'on'].includes(normalized);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const parseRepoFromRemote = () => {
|
|
39
|
+
try {
|
|
40
|
+
const remoteUrl = execSync('git config --get remote.origin.url', {
|
|
41
|
+
cwd: projectRoot,
|
|
42
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
43
|
+
})
|
|
44
|
+
.toString('utf8')
|
|
45
|
+
.trim();
|
|
46
|
+
if (!remoteUrl) return '';
|
|
47
|
+
|
|
48
|
+
const httpsMatch = remoteUrl.match(/github\.com\/([^/]+\/[^/.]+)(?:\.git)?$/i);
|
|
49
|
+
if (httpsMatch?.[1]) return httpsMatch[1];
|
|
50
|
+
|
|
51
|
+
const sshMatch = remoteUrl.match(/github\.com:([^/]+\/[^/.]+)(?:\.git)?$/i);
|
|
52
|
+
if (sshMatch?.[1]) return sshMatch[1];
|
|
53
|
+
} catch {
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
return '';
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const token = env('RELEASE_GITHUB_TOKEN', 'DEPLOY_GITHUB_TOKEN', 'GITHUB_TOKEN', 'GH_TOKEN');
|
|
60
|
+
const repository = env('RELEASE_GITHUB_REPO', 'DEPLOY_GITHUB_REPO', 'GITHUB_REPOSITORY') || parseRepoFromRemote();
|
|
61
|
+
|
|
62
|
+
if (!action || action !== 'upsert') {
|
|
63
|
+
console.error('Uso: node scripts/github-release-notify.mjs upsert --tag vX.Y.Z [opções]');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!token || !repository) {
|
|
68
|
+
console.error('GitHub release notify ignorado: token ou repositório não configurado.');
|
|
69
|
+
process.exit(2);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const [repoOwnerRaw, repoNameRaw] = repository.split('/', 2);
|
|
73
|
+
const repoOwner = String(repoOwnerRaw || '').trim();
|
|
74
|
+
const repoName = String(repoNameRaw || '').trim();
|
|
75
|
+
if (!repoOwner || !repoName) {
|
|
76
|
+
console.error('GitHub release notify ignorado: formato de repositório inválido (esperado owner/repo).');
|
|
77
|
+
process.exit(2);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const tag = getArg('--tag');
|
|
81
|
+
const target = getArg('--target');
|
|
82
|
+
const name = getArg('--name', tag);
|
|
83
|
+
const body = getArg('--body', '');
|
|
84
|
+
const generateNotes = toBool(getArg('--generate-notes', 'true'), true);
|
|
85
|
+
const prerelease = toBool(getArg('--prerelease', 'false'), false);
|
|
86
|
+
const draft = toBool(getArg('--draft', 'false'), false);
|
|
87
|
+
|
|
88
|
+
if (!tag) {
|
|
89
|
+
console.error('Parâmetro obrigatório ausente: --tag');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const headers = {
|
|
94
|
+
Accept: 'application/vnd.github+json',
|
|
95
|
+
Authorization: `Bearer ${token}`,
|
|
96
|
+
'X-GitHub-Api-Version': '2022-11-28',
|
|
97
|
+
'Content-Type': 'application/json',
|
|
98
|
+
'User-Agent': 'omnizap-release-script',
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const request = async (url, method, payload) => {
|
|
102
|
+
const response = await fetch(url, {
|
|
103
|
+
method,
|
|
104
|
+
headers,
|
|
105
|
+
body: payload ? JSON.stringify(payload) : undefined,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const raw = await response.text();
|
|
109
|
+
let data = null;
|
|
110
|
+
try {
|
|
111
|
+
data = raw ? JSON.parse(raw) : null;
|
|
112
|
+
} catch {
|
|
113
|
+
data = null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
ok: response.ok,
|
|
118
|
+
status: response.status,
|
|
119
|
+
data,
|
|
120
|
+
raw,
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const failFromResponse = (response, fallbackPrefix = 'GitHub API') => {
|
|
125
|
+
const message = response?.data?.message || response?.raw || 'unknown error';
|
|
126
|
+
throw new Error(`${fallbackPrefix} ${response?.status ?? 'n/a'}: ${message}`);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const run = async () => {
|
|
130
|
+
const baseUrl = `https://api.github.com/repos/${encodeURIComponent(repoOwner)}/${encodeURIComponent(repoName)}`;
|
|
131
|
+
|
|
132
|
+
const byTag = await request(`${baseUrl}/releases/tags/${encodeURIComponent(tag)}`, 'GET');
|
|
133
|
+
let existingRelease = null;
|
|
134
|
+
if (byTag.ok) {
|
|
135
|
+
existingRelease = byTag.data;
|
|
136
|
+
} else if (byTag.status !== 404) {
|
|
137
|
+
failFromResponse(byTag, 'GitHub API');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const commonPayload = {
|
|
141
|
+
tag_name: tag,
|
|
142
|
+
target_commitish: target || undefined,
|
|
143
|
+
name: name || tag,
|
|
144
|
+
draft,
|
|
145
|
+
prerelease,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
if (body) {
|
|
149
|
+
commonPayload.body = body;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (existingRelease) {
|
|
153
|
+
const update = await request(`${baseUrl}/releases/${existingRelease.id}`, 'PATCH', commonPayload);
|
|
154
|
+
if (!update.ok) {
|
|
155
|
+
failFromResponse(update, 'GitHub API');
|
|
156
|
+
}
|
|
157
|
+
const url = update.data?.html_url || '';
|
|
158
|
+
process.stdout.write(`updated id=${update.data?.id} tag=${tag} url=${url}`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const createPayload = { ...commonPayload };
|
|
163
|
+
if (generateNotes) {
|
|
164
|
+
createPayload.generate_release_notes = true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const created = await request(`${baseUrl}/releases`, 'POST', createPayload);
|
|
168
|
+
if (!created.ok) {
|
|
169
|
+
failFromResponse(created, 'GitHub API');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const url = created.data?.html_url || '';
|
|
173
|
+
process.stdout.write(`created id=${created.data?.id} tag=${tag} url=${url}`);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
run().catch((error) => {
|
|
177
|
+
console.error(error?.message || error);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
});
|
|
180
|
+
|
package/scripts/release.sh
CHANGED
|
@@ -10,6 +10,13 @@ RELEASE_GIT_BRANCH="${RELEASE_GIT_BRANCH:-}"
|
|
|
10
10
|
RELEASE_GIT_PRE_COMMIT_MESSAGE="${RELEASE_GIT_PRE_COMMIT_MESSAGE:-chore(release): auto-commit before release}"
|
|
11
11
|
RELEASE_GIT_COMMIT_VERSION="${RELEASE_GIT_COMMIT_VERSION:-1}"
|
|
12
12
|
RELEASE_GIT_VERSION_COMMIT_PREFIX="${RELEASE_GIT_VERSION_COMMIT_PREFIX:-chore(release): v}"
|
|
13
|
+
RELEASE_GITHUB_RELEASE="${RELEASE_GITHUB_RELEASE:-1}"
|
|
14
|
+
RELEASE_GITHUB_TAG_PREFIX="${RELEASE_GITHUB_TAG_PREFIX:-v}"
|
|
15
|
+
RELEASE_GITHUB_NAME_PREFIX="${RELEASE_GITHUB_NAME_PREFIX:-v}"
|
|
16
|
+
RELEASE_GITHUB_GENERATE_NOTES="${RELEASE_GITHUB_GENERATE_NOTES:-1}"
|
|
17
|
+
RELEASE_GITHUB_PRERELEASE="${RELEASE_GITHUB_PRERELEASE:-}"
|
|
18
|
+
RELEASE_GITHUB_DRAFT="${RELEASE_GITHUB_DRAFT:-0}"
|
|
19
|
+
RELEASE_GITHUB_TARGET="${RELEASE_GITHUB_TARGET:-}"
|
|
13
20
|
|
|
14
21
|
case "$RELEASE_TYPE" in
|
|
15
22
|
patch|minor|major|prepatch|preminor|premajor|prerelease)
|
|
@@ -86,12 +93,26 @@ commit_and_push_if_dirty() {
|
|
|
86
93
|
|
|
87
94
|
require_cmd git
|
|
88
95
|
require_cmd npm
|
|
96
|
+
require_cmd node
|
|
89
97
|
|
|
90
98
|
if ! (cd "$PROJECT_ROOT" && git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
|
|
91
99
|
printf '[release] este diretório não é um repositório git válido.\n' >&2
|
|
92
100
|
exit 1
|
|
93
101
|
fi
|
|
94
102
|
|
|
103
|
+
to_bool() {
|
|
104
|
+
local value
|
|
105
|
+
value="$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')"
|
|
106
|
+
case "$value" in
|
|
107
|
+
1|true|yes|on)
|
|
108
|
+
printf 'true'
|
|
109
|
+
;;
|
|
110
|
+
*)
|
|
111
|
+
printf 'false'
|
|
112
|
+
;;
|
|
113
|
+
esac
|
|
114
|
+
}
|
|
115
|
+
|
|
95
116
|
commit_and_push_if_dirty "$RELEASE_GIT_PRE_COMMIT_MESSAGE"
|
|
96
117
|
|
|
97
118
|
current_version="$(cd "$PROJECT_ROOT" && npm pkg get version | tr -d '"[:space:]')"
|
|
@@ -126,4 +147,46 @@ if [ "$RELEASE_GIT_COMMIT_VERSION" = "1" ]; then
|
|
|
126
147
|
commit_and_push_if_dirty "${RELEASE_GIT_VERSION_COMMIT_PREFIX}${new_version}"
|
|
127
148
|
fi
|
|
128
149
|
|
|
150
|
+
if [ "$RELEASE_GITHUB_RELEASE" = "1" ]; then
|
|
151
|
+
if [ "$RELEASE_GIT_AUTO_PUSH" != "1" ]; then
|
|
152
|
+
printf '[release] RELEASE_GITHUB_RELEASE=1 requer RELEASE_GIT_AUTO_PUSH=1 para garantir commit acessível no GitHub.\n' >&2
|
|
153
|
+
exit 1
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
local_tag="${RELEASE_GITHUB_TAG_PREFIX}${new_version}"
|
|
157
|
+
local_name="${RELEASE_GITHUB_NAME_PREFIX}${new_version}"
|
|
158
|
+
local_target="$RELEASE_GITHUB_TARGET"
|
|
159
|
+
if [ -z "$local_target" ]; then
|
|
160
|
+
local_target="$(cd "$PROJECT_ROOT" && git rev-parse HEAD)"
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
local_prerelease="$RELEASE_GITHUB_PRERELEASE"
|
|
164
|
+
if [ -z "$local_prerelease" ]; then
|
|
165
|
+
if printf '%s' "$new_version" | grep -q '-'; then
|
|
166
|
+
local_prerelease="1"
|
|
167
|
+
else
|
|
168
|
+
local_prerelease="0"
|
|
169
|
+
fi
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
local generate_notes_bool=""
|
|
173
|
+
generate_notes_bool="$(to_bool "$RELEASE_GITHUB_GENERATE_NOTES")"
|
|
174
|
+
local prerelease_bool=""
|
|
175
|
+
prerelease_bool="$(to_bool "$local_prerelease")"
|
|
176
|
+
local draft_bool=""
|
|
177
|
+
draft_bool="$(to_bool "$RELEASE_GITHUB_DRAFT")"
|
|
178
|
+
|
|
179
|
+
log "Criando/atualizando GitHub Release ($local_tag)"
|
|
180
|
+
release_output="$(
|
|
181
|
+
cd "$PROJECT_ROOT" && node ./scripts/github-release-notify.mjs upsert \
|
|
182
|
+
--tag "$local_tag" \
|
|
183
|
+
--target "$local_target" \
|
|
184
|
+
--name "$local_name" \
|
|
185
|
+
--generate-notes "$generate_notes_bool" \
|
|
186
|
+
--prerelease "$prerelease_bool" \
|
|
187
|
+
--draft "$draft_bool"
|
|
188
|
+
)"
|
|
189
|
+
log "GitHub Release atualizado: $release_output"
|
|
190
|
+
fi
|
|
191
|
+
|
|
129
192
|
log "Release concluída: $new_version"
|