@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 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 do package (com auto commit/push git).
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaikybrofc/omnizap-system",
3
- "version": "2.1.8",
3
+ "version": "2.1.10",
4
4
  "description": "Sistema profissional de automação WhatsApp com tecnologia Baileys",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
@@ -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
+
@@ -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"