@vv0rkz/js-template 1.4.3 → 1.5.0
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/bin/cli.js +114 -24
- package/bin/init.js +10 -3
- package/package.json +1 -1
- package/templates/README.md +1 -1
- package/templates/changelog.config.js +7 -7
- package/tools-gh/create-perf.js +51 -0
- package/tools-gh/create-refactor.js +50 -0
- package/tools-gh/push-release-to-main.js +39 -14
- package/tools-gh/setup-labels.js +4 -5
package/bin/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { fileURLToPath } from 'url'
|
|
3
|
-
import { dirname, join } from 'path'
|
|
4
2
|
import { spawnSync } from 'child_process'
|
|
5
3
|
import { platform } from 'os'
|
|
4
|
+
import { dirname, join } from 'path'
|
|
5
|
+
import { fileURLToPath } from 'url'
|
|
6
6
|
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
8
8
|
const toolsDir = join(__dirname, '../tools-gh')
|
|
@@ -38,20 +38,34 @@ const commands = {
|
|
|
38
38
|
release: () => {
|
|
39
39
|
console.log('🚀 Запуск релиза...\n')
|
|
40
40
|
|
|
41
|
+
// 1. Проверка демо
|
|
41
42
|
const checkDemo = spawnSync('node', [join(toolsDir, 'check-demo-for-release.js')], { stdio: 'inherit' })
|
|
42
43
|
if (checkDemo.status !== 0) {
|
|
43
44
|
console.error('❌ Проверка демо не прошла')
|
|
44
45
|
process.exit(1)
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
// 2. Определяем тип bump из коммитов
|
|
49
|
+
const commitMessages = execSync('git log --oneline -10', { encoding: 'utf8' })
|
|
50
|
+
const bumpType = commitMessages.includes('feat:') ? 'minor' : 'patch'
|
|
51
|
+
|
|
52
|
+
// 3. Создаём changelog
|
|
53
|
+
const changelog = spawnSync(npxCmd, ['changelogen', '--release', '--bump', bumpType], { stdio: 'inherit' })
|
|
48
54
|
if (changelog.status !== 0) {
|
|
49
55
|
console.error('❌ Ошибка создания changelog')
|
|
50
56
|
process.exit(1)
|
|
51
57
|
}
|
|
52
58
|
|
|
53
|
-
|
|
59
|
+
// 4. Обновляем README ← ДОБАВЬ ЭТО
|
|
60
|
+
console.log('\n📝 Обновление README...')
|
|
61
|
+
const updateReadme = spawnSync('node', [join(toolsDir, 'update-readme.js')], { stdio: 'inherit' })
|
|
62
|
+
if (updateReadme.status !== 0) {
|
|
63
|
+
console.log('⚠️ README не обновлён (возможно нет секции AUTOGENERATED)')
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
console.log('\n✅ Релиз успешно создан!')
|
|
67
|
+
console.log('💡 Теперь можно:')
|
|
68
|
+
console.log(' npm run _ push-release # Запушить в main')
|
|
55
69
|
},
|
|
56
70
|
|
|
57
71
|
'update-readme': () => {
|
|
@@ -92,10 +106,74 @@ const commands = {
|
|
|
92
106
|
}
|
|
93
107
|
},
|
|
94
108
|
|
|
109
|
+
'create-refactor': () => {
|
|
110
|
+
const args = process.argv.slice(3)
|
|
111
|
+
spawnSync('node', [join(toolsDir, 'create-refactor.js'), ...args], { stdio: 'inherit' })
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
refactors: () => {
|
|
115
|
+
spawnSync(ghCmd, ['issue', 'list', '--label', 'refactor'], { stdio: 'inherit' })
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
'create-perf': () => {
|
|
119
|
+
const args = process.argv.slice(3)
|
|
120
|
+
spawnSync('node', [join(toolsDir, 'create-perf.js'), ...args], { stdio: 'inherit' })
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
perfs: () => {
|
|
124
|
+
spawnSync(ghCmd, ['issue', 'list', '--label', 'perf'], { stdio: 'inherit' })
|
|
125
|
+
},
|
|
126
|
+
|
|
95
127
|
'all-issues': () => {
|
|
96
128
|
// БЕЗ shell: true
|
|
97
129
|
spawnSync(ghCmd, ['issue', 'list', '--state', 'open'], { stdio: 'inherit' })
|
|
98
130
|
},
|
|
131
|
+
'pr-list': () => {
|
|
132
|
+
console.log('📋 Список Pull Requests...\n')
|
|
133
|
+
spawnSync('gh', ['pr', 'list'], { stdio: 'inherit' })
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
'pr-view': () => {
|
|
137
|
+
const prNumber = process.argv[3]
|
|
138
|
+
if (!prNumber) {
|
|
139
|
+
console.log('❌ Укажи номер PR: npm run _ pr-view 5')
|
|
140
|
+
process.exit(1)
|
|
141
|
+
}
|
|
142
|
+
console.log(`👀 Просмотр PR #${prNumber}...\n`)
|
|
143
|
+
spawnSync('gh', ['pr', 'view', prNumber], { stdio: 'inherit' })
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
'pr-view-web': () => {
|
|
147
|
+
const prNumber = process.argv[3]
|
|
148
|
+
if (!prNumber) {
|
|
149
|
+
console.log('❌ Укажи номер PR: npm run _ pr-view-web 5')
|
|
150
|
+
process.exit(1)
|
|
151
|
+
}
|
|
152
|
+
console.log(`🌐 Открываю PR #${prNumber} в браузере...`)
|
|
153
|
+
spawnSync('gh', ['pr', 'view', prNumber, '--web'], { stdio: 'inherit' })
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
'pr-merge': () => {
|
|
157
|
+
const prNumber = process.argv[3]
|
|
158
|
+
if (!prNumber) {
|
|
159
|
+
console.log('❌ Укажи номер PR: npm run _ pr-merge 5')
|
|
160
|
+
process.exit(1)
|
|
161
|
+
}
|
|
162
|
+
console.log(`🔀 Мерджу PR #${prNumber}...\n`)
|
|
163
|
+
spawnSync('gh', ['pr', 'merge', prNumber, '--merge'], { stdio: 'inherit' })
|
|
164
|
+
console.log('\n✅ PR смерджен!')
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
'pr-close': () => {
|
|
168
|
+
const prNumber = process.argv[3]
|
|
169
|
+
if (!prNumber) {
|
|
170
|
+
console.log('❌ Укажи номер PR: npm run _ pr-close 5')
|
|
171
|
+
process.exit(1)
|
|
172
|
+
}
|
|
173
|
+
console.log(`❌ Закрываю PR #${prNumber}...\n`)
|
|
174
|
+
spawnSync('gh', ['pr', 'close', prNumber], { stdio: 'inherit' })
|
|
175
|
+
console.log('\n✅ PR закрыт!')
|
|
176
|
+
},
|
|
99
177
|
}
|
|
100
178
|
|
|
101
179
|
if (commands[command]) {
|
|
@@ -104,32 +182,44 @@ if (commands[command]) {
|
|
|
104
182
|
console.log(`
|
|
105
183
|
⚡ JS Template CLI
|
|
106
184
|
|
|
107
|
-
Использование:
|
|
185
|
+
Использование: npm run _ <команда> [аргументы]
|
|
108
186
|
|
|
109
187
|
📋 ПРОЕКТ:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
188
|
+
init Инициализация проекта
|
|
189
|
+
init-readme Создать стартовый README.md
|
|
190
|
+
setup-labels Настроить GitHub labels
|
|
113
191
|
|
|
114
192
|
🔧 РАЗРАБОТКА:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
193
|
+
update-readme Обновить README с версией
|
|
194
|
+
release Полный релиз (проверка + changelog + README)
|
|
195
|
+
push-release Создать PR и смерджить в main
|
|
196
|
+
|
|
197
|
+
📝 ISSUES:
|
|
198
|
+
tasks Список задач (фичи)
|
|
199
|
+
create-task [название] Создать задачу
|
|
200
|
+
bugs Список багов
|
|
201
|
+
create-bug [название] Создать баг
|
|
202
|
+
refactors Список рефакторингов
|
|
203
|
+
create-refactor [название] Создать рефакторинг
|
|
204
|
+
perfs Список оптимизаций
|
|
205
|
+
create-perf [название] Создать оптимизацию
|
|
206
|
+
all-issues Все issues
|
|
207
|
+
|
|
208
|
+
🔀 PULL REQUESTS:
|
|
209
|
+
pr-list Показать все PR
|
|
210
|
+
pr-view <number> Посмотреть PR в терминале
|
|
211
|
+
pr-view-web <number> Открыть PR в браузере
|
|
212
|
+
pr-merge <number> Смерджить PR
|
|
213
|
+
pr-close <number> Закрыть PR без merge
|
|
126
214
|
|
|
127
215
|
📚 ПРИМЕРЫ:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
216
|
+
npm run _ init
|
|
217
|
+
npm run _ init-readme
|
|
218
|
+
npm run _ feat "Добавить темную тему"
|
|
219
|
+
npm run _ release
|
|
220
|
+
npm run _ pr-list
|
|
221
|
+
npm run _ pr-merge 5
|
|
222
|
+
|
|
133
223
|
`)
|
|
134
224
|
process.exit(command ? 1 : 0)
|
|
135
225
|
}
|
package/bin/init.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { fileURLToPath } from 'url'
|
|
3
|
-
import { dirname, join } from 'path'
|
|
4
|
-
import { copyFileSync, mkdirSync, existsSync, readFileSync, writeFileSync, readdirSync, statSync, unlinkSync } from 'fs'
|
|
5
2
|
import { execSync, spawnSync } from 'child_process'
|
|
3
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from 'fs'
|
|
4
|
+
import { dirname, join } from 'path'
|
|
6
5
|
import * as readline from 'readline'
|
|
6
|
+
import { fileURLToPath } from 'url'
|
|
7
7
|
|
|
8
8
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
9
9
|
const templateDir = join(__dirname, '../templates')
|
|
@@ -186,6 +186,13 @@ try {
|
|
|
186
186
|
console.log(' Запусти позже: npm run _ setup-labels')
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
// 8. Инициализация README
|
|
190
|
+
console.log('\n📝 Инициализация README...')
|
|
191
|
+
const initReadme = spawnSync('node', [join(toolsDir, 'init-readme.js')], { stdio: 'inherit' })
|
|
192
|
+
if (initReadme.status === 0) {
|
|
193
|
+
console.log(' ✅ README.md создан')
|
|
194
|
+
}
|
|
195
|
+
|
|
189
196
|
console.log(`
|
|
190
197
|
🎉 JS Template успешно установлен!
|
|
191
198
|
|
package/package.json
CHANGED
package/templates/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
types: {
|
|
3
|
+
feat: { title: '✨ Новые фичи', semver: 'minor' },
|
|
4
|
+
fix: { title: '🐛 Исправления', semver: 'patch' },
|
|
5
|
+
refactor: { title: '♻️ Рефакторинг', semver: 'patch' },
|
|
6
|
+
perf: { title: '⚡ Оптимизация', semver: 'patch' },
|
|
7
|
+
},
|
|
8
|
+
contributors: false,
|
|
9
9
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'child_process'
|
|
3
|
+
|
|
4
|
+
const args = process.argv.slice(2)
|
|
5
|
+
const title = args.join(' ')
|
|
6
|
+
|
|
7
|
+
if (!title) {
|
|
8
|
+
console.log('❌ Использование: jst create-perf "описание оптимизации"')
|
|
9
|
+
console.log(' или: npm run _ create-perf "описание оптимизации"')
|
|
10
|
+
process.exit(1)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
console.log('⚡ Создаю задачу на оптимизацию...')
|
|
15
|
+
|
|
16
|
+
execSync(`gh issue create --title "Perf: ${title}" --body "Оптимизация: ${title}" --label "perf"`, {
|
|
17
|
+
stdio: 'inherit',
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
console.log('⚡ Задача на оптимизацию создана!')
|
|
21
|
+
} catch (error) {
|
|
22
|
+
if (error.message.includes("'perf' not found") || error.stderr?.includes("'perf' not found")) {
|
|
23
|
+
console.log("\n⚠️ Label 'perf' не найден. Создаю автоматически...")
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
execSync('gh label create perf --color "FF6B6B" --description "Оптимизация производительности"', {
|
|
27
|
+
stdio: 'ignore',
|
|
28
|
+
})
|
|
29
|
+
console.log("✅ Label 'perf' создан")
|
|
30
|
+
|
|
31
|
+
console.log('⚡ Создаю задачу на оптимизацию...')
|
|
32
|
+
execSync(`gh issue create --title "Perf: ${title}" --body "Оптимизация: ${title}" --label "perf"`, {
|
|
33
|
+
stdio: 'inherit',
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
console.log('⚡ Задача на оптимизацию создана!')
|
|
37
|
+
} catch (retryError) {
|
|
38
|
+
console.error('❌ Ошибка создания задачи:', retryError.message)
|
|
39
|
+
console.log('\n💡 Попробуй:')
|
|
40
|
+
console.log(' npm run _ setup-labels')
|
|
41
|
+
process.exit(1)
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
console.error('❌ Ошибка создания задачи:', error.message)
|
|
45
|
+
console.log('\n💡 Убедись что:')
|
|
46
|
+
console.log(' 1. Установлен GitHub CLI: gh --version')
|
|
47
|
+
console.log(' 2. Выполнена авторизация: gh auth login')
|
|
48
|
+
console.log(' 3. Создан репозиторий на GitHub')
|
|
49
|
+
process.exit(1)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'child_process'
|
|
3
|
+
|
|
4
|
+
const args = process.argv.slice(2)
|
|
5
|
+
const title = args.join(' ')
|
|
6
|
+
|
|
7
|
+
if (!title) {
|
|
8
|
+
console.log('❌ Использование: jst create-refactor "описание рефакторинга"')
|
|
9
|
+
console.log(' или: npm run _ create-refactor "описание рефакторинга"')
|
|
10
|
+
process.exit(1)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
console.log('♻️ Создаю задачу на рефакторинг...')
|
|
15
|
+
|
|
16
|
+
execSync(`gh issue create --title "Refactor: ${title}" --body "Рефакторинг: ${title}" --label "refactor"`, {
|
|
17
|
+
stdio: 'inherit',
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
console.log('♻️ Задача на рефакторинг создана!')
|
|
21
|
+
} catch (error) {
|
|
22
|
+
if (error.message.includes("'refactor' not found") || error.stderr?.includes("'refactor' not found")) {
|
|
23
|
+
console.log("\n⚠️ Label 'refactor' не найден. Создаю автоматически...")
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
execSync('gh label create refactor --color "FEF2C0" --description "Рефакторинг/техдолг"', { stdio: 'ignore' })
|
|
27
|
+
console.log("✅ Label 'refactor' создан")
|
|
28
|
+
|
|
29
|
+
console.log('♻️ Создаю задачу на рефакторинг...')
|
|
30
|
+
execSync(`gh issue create --title "Refactor: ${title}" --body "Рефакторинг: ${title}" --label "refactor"`, {
|
|
31
|
+
stdio: 'inherit',
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
console.log('♻️ Задача на рефакторинг создана!')
|
|
35
|
+
} catch (retryError) {
|
|
36
|
+
console.error('❌ Ошибка создания задачи:', retryError.message)
|
|
37
|
+
console.log('\n💡 Попробуй:')
|
|
38
|
+
console.log(' npm run _ setup-labels')
|
|
39
|
+
process.exit(1)
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
console.error('❌ Ошибка создания задачи:', error.message)
|
|
43
|
+
console.log('\n💡 Убедись что:')
|
|
44
|
+
console.log(' 1. Установлен GitHub CLI: gh --version')
|
|
45
|
+
console.log(' 2. Выполнена авторизация: gh auth login')
|
|
46
|
+
console.log(' 3. Создан репозиторий на GitHub')
|
|
47
|
+
process.exit(1)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
1
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execSync } from 'child_process'
|
|
3
3
|
|
|
4
|
-
console.log('🚀
|
|
4
|
+
console.log('🚀 Создание Pull Request для релиза...')
|
|
5
5
|
|
|
6
6
|
try {
|
|
7
7
|
// 1. Получаем текущую ветку
|
|
@@ -22,27 +22,52 @@ try {
|
|
|
22
22
|
process.exit(1)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
// 3.
|
|
25
|
+
// 3. Проверяем что ветка запушена
|
|
26
|
+
console.log('📤 Пушим изменения в удалённую ветку...')
|
|
27
|
+
try {
|
|
28
|
+
execSync(`git push origin ${currentBranch} --follow-tags`, { stdio: 'inherit' })
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.log('⚠️ Ветка уже запушена или произошла ошибка')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 4. Определяем главную ветку (main или master)
|
|
26
34
|
let mainBranch = 'main'
|
|
27
35
|
try {
|
|
28
|
-
execSync('git rev-parse --verify main', { stdio: 'ignore' })
|
|
36
|
+
execSync('git rev-parse --verify origin/main', { stdio: 'ignore' })
|
|
29
37
|
} catch {
|
|
30
38
|
mainBranch = 'master'
|
|
31
39
|
}
|
|
32
40
|
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
// 5. Получаем последний тег (версию релиза)
|
|
42
|
+
let version = 'Release'
|
|
43
|
+
try {
|
|
44
|
+
version = execSync('git describe --tags --abbrev=0').toString().trim()
|
|
45
|
+
} catch {
|
|
46
|
+
console.log('⚠️ Тег не найден, используется дефолтное название')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 6. Создаём Pull Request через GitHub CLI
|
|
50
|
+
console.log('\n🔀 Создаю Pull Request...')
|
|
51
|
+
|
|
52
|
+
const prTitle = `Release ${version}`
|
|
53
|
+
const prBody = `Релиз версии ${version}\n\nСм. CHANGELOG.md для деталей.`
|
|
54
|
+
|
|
55
|
+
execSync(`gh pr create --base ${mainBranch} --head ${currentBranch} --title "${prTitle}" --body "${prBody}"`, {
|
|
56
|
+
stdio: 'inherit',
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
console.log(`\n✅ Pull Request создан!`)
|
|
37
60
|
|
|
38
|
-
//
|
|
39
|
-
console.log('
|
|
40
|
-
execSync(
|
|
41
|
-
execSync('git push --tags', { stdio: 'inherit' })
|
|
61
|
+
// 7. Автоматический merge БЕЗ удаления ветки
|
|
62
|
+
console.log('\n🔀 Мерджу PR...')
|
|
63
|
+
execSync('gh pr merge --merge', { stdio: 'inherit' })
|
|
42
64
|
|
|
43
|
-
console.log(
|
|
44
|
-
console.log(`💡
|
|
65
|
+
console.log(`\n✅ Релиз ${version} завершён!`)
|
|
66
|
+
console.log(`💡 Ветка ${currentBranch} сохранена в истории`)
|
|
45
67
|
} catch (error) {
|
|
46
|
-
console.error('❌ Ошибка при
|
|
68
|
+
console.error('❌ Ошибка при создании/мердже PR:', error.message)
|
|
69
|
+
console.log('\n💡 Убедись что:')
|
|
70
|
+
console.log(' 1. Установлен GitHub CLI: gh --version')
|
|
71
|
+
console.log(' 2. Выполнена авторизация: gh auth login')
|
|
47
72
|
process.exit(1)
|
|
48
73
|
}
|
package/tools-gh/setup-labels.js
CHANGED
|
@@ -4,11 +4,10 @@ import { execSync } from 'child_process'
|
|
|
4
4
|
console.log('🏷️ Настройка GitHub labels...\n')
|
|
5
5
|
|
|
6
6
|
const labels = [
|
|
7
|
-
{ name: 'task', color: '0E8A16', description: '
|
|
8
|
-
{ name: 'bug', color: 'D73A4A', description: 'Баг
|
|
9
|
-
{ name: '
|
|
10
|
-
{ name: '
|
|
11
|
-
{ name: 'question', color: 'D876E3', description: 'Вопрос' },
|
|
7
|
+
{ name: 'task', color: '0E8A16', description: 'Новая фича' },
|
|
8
|
+
{ name: 'bug', color: 'D73A4A', description: 'Баг' },
|
|
9
|
+
{ name: 'refactor', color: 'FEF2C0', description: 'Рефакторинг/техдолг' },
|
|
10
|
+
{ name: 'perf', color: 'FF6B6B', description: 'Оптимизация производительности' },
|
|
12
11
|
]
|
|
13
12
|
|
|
14
13
|
try {
|