Skip to content

Commit 30e05eb

Browse files
committed
chore: minor setup improvements
chore: lint
1 parent 5376ec8 commit 30e05eb

File tree

3 files changed

+141
-105
lines changed

3 files changed

+141
-105
lines changed

bin/cli.ts

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -230,47 +230,13 @@ cli
230230
displayProgress(progress)
231231

232232
console.log('\n🔑 GitHub Token Setup')
233-
console.log('For full functionality, Buddy Bot needs a Personal Access Token (PAT).')
233+
console.log('For full functionality, Buddy Bot needs appropriate GitHub permissions.')
234234
console.log('This enables workflow file updates and advanced GitHub Actions features.\n')
235235

236-
const tokenResponse = await prompts([
237-
{
238-
type: 'select',
239-
name: 'tokenSetup',
240-
message: 'Do you have a GitHub Personal Access Token with \'repo\' and \'workflow\' scopes?',
241-
choices: [
242-
{
243-
title: 'Yes, I have a token ready',
244-
description: 'I\'ll provide the token or set it up as a repository secret',
245-
value: 'have-token',
246-
},
247-
{
248-
title: 'No, guide me through creating one',
249-
description: 'Show me how to create a Personal Access Token',
250-
value: 'create-token',
251-
},
252-
{
253-
title: 'Skip for now, use limited permissions',
254-
description: 'Use GITHUB_TOKEN only (workflow updates won\'t work)',
255-
value: 'skip-token',
256-
},
257-
],
258-
},
259-
])
236+
const tokenSetup = await confirmTokenSetup()
260237

261-
if (!tokenResponse.tokenSetup) {
262-
console.log('Setup cancelled.')
263-
return
264-
}
265-
266-
let hasCustomToken = false
267-
268-
if (tokenResponse.tokenSetup === 'create-token') {
238+
if (tokenSetup.needsGuide) {
269239
await guideTokenCreation(repoInfo)
270-
hasCustomToken = await confirmTokenSetup()
271-
}
272-
else if (tokenResponse.tokenSetup === 'have-token') {
273-
hasCustomToken = await confirmTokenSetup()
274240
}
275241

276242
// Step 3: Repository Settings
@@ -335,7 +301,7 @@ cli
335301
displayProgress(progress)
336302

337303
console.log('\n📝 Configuration File')
338-
await generateConfigFile(repoInfo, hasCustomToken)
304+
await generateConfigFile(repoInfo, tokenSetup.hasCustomToken)
339305

340306
// Step 6: Generate Workflows
341307
updateProgress(progress, 'Workflow Generation', true)
@@ -353,7 +319,7 @@ cli
353319
}
354320

355321
// Generate the core workflows based on the provided templates
356-
await generateCoreWorkflows(preset, repoInfo, hasCustomToken, logger)
322+
await generateCoreWorkflows(preset, repoInfo, tokenSetup.hasCustomToken, logger)
357323

358324
// Step 7: Workflow Validation
359325
updateProgress(progress, 'Workflow Validation', true)
@@ -400,7 +366,7 @@ cli
400366
displayProgress(progress)
401367

402368
console.log('\n🎉 Setup Complete!')
403-
await showFinalInstructions(repoInfo, hasCustomToken)
369+
await showFinalInstructions(repoInfo, tokenSetup.hasCustomToken)
404370

405371
// Execute plugin hooks for setup completion
406372
if (availablePlugins.length > 0) {

src/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { BuddyBotConfig } from './types'
2-
import { resolve } from 'node:path'
32
import { loadConfig } from 'bunfig'
3+
import process from 'node:process'
44

55
export const defaultConfig: BuddyBotConfig = {
66
verbose: true,
@@ -9,6 +9,6 @@ export const defaultConfig: BuddyBotConfig = {
99
// eslint-disable-next-line antfu/no-top-level-await
1010
export const config: BuddyBotConfig = await loadConfig({
1111
name: 'buddy-bot',
12-
cwd: resolve(__dirname, '..'),
12+
cwd: process.cwd(),
1313
defaultConfig,
1414
})

src/setup.ts

Lines changed: 133 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ export function createProgressTracker(totalSteps: number): SetupProgress {
895895
}
896896

897897
export function updateProgress(progress: SetupProgress, stepName: string, completed?: boolean): SetupProgress {
898-
if (completed && !progress.completed.includes(progress.stepName)) {
898+
if (completed && progress.stepName && !progress.completed.includes(progress.stepName)) {
899899
progress.completed.push(progress.stepName)
900900
}
901901

@@ -908,11 +908,16 @@ export function updateProgress(progress: SetupProgress, stepName: string, comple
908908
}
909909

910910
export function displayProgress(progress: SetupProgress): void {
911-
const percentage = Math.round((progress.currentStep / progress.totalSteps) * 100)
912-
const progressBar = '█'.repeat(Math.floor(percentage / 5)) + '░'.repeat(20 - Math.floor(percentage / 5))
911+
// Ensure currentStep doesn't exceed totalSteps to prevent negative percentages
912+
const currentStep = Math.min(progress.currentStep, progress.totalSteps)
913+
const percentage = Math.round((currentStep / progress.totalSteps) * 100)
914+
915+
// Ensure the progress bar calculation is valid (0-20 range)
916+
const progressBlocks = Math.max(0, Math.min(20, Math.floor(percentage / 5)))
917+
const progressBar = '█'.repeat(progressBlocks) + '░'.repeat(20 - progressBlocks)
913918

914919
console.log(`\n📊 Setup Progress: ${percentage}% [${progressBar}]`)
915-
console.log(`🔄 Current Step: ${progress.stepName} (${progress.currentStep}/${progress.totalSteps})`)
920+
console.log(`🔄 Current Step: ${progress.stepName} (${currentStep}/${progress.totalSteps})`)
916921

917922
if (progress.completed.length > 0) {
918923
console.log(`✅ Completed: ${progress.completed.join(', ')}`)
@@ -937,30 +942,84 @@ export async function detectRepository(): Promise<RepositoryInfo | null> {
937942
}
938943

939944
export async function guideTokenCreation(repoInfo: RepositoryInfo): Promise<void> {
940-
console.log(`\n🔑 To create a Personal Access Token (PAT):`)
945+
console.log(`\n🔑 Personal Access Token Setup Guide:`)
946+
console.log(`\n📋 Step 1: Create the Token`)
941947
console.log(`1. Go to https://github.com/settings/tokens`)
942-
console.log(`2. Click "Generate new token"`)
943-
console.log(`3. Give it a name (e.g., "buddy-bot-token")`)
944-
console.log(`4. Select scopes:`)
945-
console.log(` - ` + 'repo' + ` (Full control of private repositories)`)
946-
console.log(` - ` + 'workflow' + ` (Read and write permissions for GitHub Actions)`)
947-
console.log(`5. Click "Generate token"`)
948-
console.log(`6. Copy the token and set it as a repository secret:`)
949-
console.log(` - Go to your repository settings (https://github.com/${repoInfo.owner}/${repoInfo.name}/settings/secrets/actions)`)
948+
console.log(`2. Click "Generate new token (classic)"`)
949+
console.log(`3. Give it a descriptive name (e.g., "buddy-bot-${repoInfo.name}")`)
950+
console.log(`4. Set expiration (recommended: 90 days or custom)`)
951+
console.log(`5. Select required scopes:`)
952+
console.log(` ✅ repo (Full control of private repositories)`)
953+
console.log(` ✅ workflow (Update GitHub Action workflows)`)
954+
console.log(`6. Click "Generate token"`)
955+
console.log(`7. ⚠️ Copy the token immediately (you won't see it again!)`)
956+
957+
console.log(`\n📋 Step 2: Configure the Secret`)
958+
console.log(`Choose one of these options:`)
959+
console.log(`\n🏢 Option A: Organization Secret (Recommended for multiple repos)`)
960+
console.log(` - Go to: https://github.com/organizations/${repoInfo.owner}/settings/secrets/actions`)
961+
console.log(` - Click "New organization secret"`)
962+
console.log(` - Name: BUDDY_BOT_TOKEN`)
963+
console.log(` - Value: your_generated_token`)
964+
console.log(` - Repository access: Selected repositories or All repositories`)
965+
966+
console.log(`\n📦 Option B: Repository Secret (For this repository only)`)
967+
console.log(` - Go to: https://github.com/${repoInfo.owner}/${repoInfo.name}/settings/secrets/actions`)
950968
console.log(` - Click "New repository secret"`)
951-
console.log(` - Name: ` + 'BUDDY_BOT_TOKEN' + `, Value: your_generated_token`)
969+
console.log(` - Name: BUDDY_BOT_TOKEN`)
970+
console.log(` - Value: your_generated_token`)
952971
console.log(` - Click "Add secret"`)
953-
console.log(`7. After adding the secret, Buddy Bot will use it for workflow updates.\n`)
972+
973+
console.log(`\n💡 The workflows will automatically use BUDDY_BOT_TOKEN if available, otherwise fall back to GITHUB_TOKEN`)
954974
}
955975

956-
export async function confirmTokenSetup(): Promise<boolean> {
976+
export async function confirmTokenSetup(): Promise<{ hasCustomToken: boolean, needsGuide: boolean }> {
977+
console.log('\n🔑 GitHub Token Configuration:')
978+
console.log('Buddy Bot can work with:')
979+
console.log(' • Organization secrets (GITHUB_TOKEN or custom PAT)')
980+
console.log(' • Repository secrets (custom PAT)')
981+
console.log(' • Default GITHUB_TOKEN (limited permissions)')
982+
console.log('')
983+
957984
const response = await prompts({
958-
type: 'confirm',
959-
name: 'useCustomToken',
960-
message: 'Do you want to use a custom GitHub Personal Access Token (PAT) for workflow updates?',
961-
initial: false,
985+
type: 'select',
986+
name: 'tokenChoice',
987+
message: 'How would you like to configure GitHub authentication?',
988+
choices: [
989+
{
990+
title: 'Use organization/repository secrets',
991+
description: 'I have already configured PAT as an organization or repository secret',
992+
value: 'existing-secret',
993+
},
994+
{
995+
title: 'Set up a new Personal Access Token',
996+
description: 'Guide me through creating and configuring a new PAT',
997+
value: 'new-pat',
998+
},
999+
{
1000+
title: 'Use default GITHUB_TOKEN only',
1001+
description: 'Limited functionality - workflow updates won\'t work',
1002+
value: 'default-token',
1003+
},
1004+
],
1005+
initial: 0,
9621006
})
963-
return response.useCustomToken
1007+
1008+
// Handle user cancellation
1009+
if (!response.tokenChoice) {
1010+
console.log('Using default GITHUB_TOKEN (limited functionality)')
1011+
return { hasCustomToken: false, needsGuide: false }
1012+
}
1013+
1014+
switch (response.tokenChoice) {
1015+
case 'existing-secret':
1016+
return { hasCustomToken: true, needsGuide: false }
1017+
case 'new-pat':
1018+
return { hasCustomToken: true, needsGuide: true }
1019+
case 'default-token':
1020+
default:
1021+
return { hasCustomToken: false, needsGuide: false }
1022+
}
9641023
}
9651024

9661025
export async function guideRepositorySettings(repoInfo: RepositoryInfo): Promise<void> {
@@ -974,40 +1033,48 @@ export async function guideRepositorySettings(repoInfo: RepositoryInfo): Promise
9741033
}
9751034

9761035
export async function generateConfigFile(repoInfo: RepositoryInfo, hasCustomToken: boolean): Promise<void> {
977-
const configContent = JSON.stringify({
978-
repository: {
979-
owner: repoInfo.owner,
980-
name: repoInfo.name,
981-
provider: 'github' as const,
982-
token: hasCustomToken ? undefined : process.env.GITHUB_TOKEN,
1036+
const configContent = `import type { BuddyBotConfig } from 'buddy-bot'
1037+
1038+
const config: BuddyBotConfig = {
1039+
repository: {
1040+
owner: '${repoInfo.owner}',
1041+
name: '${repoInfo.name}',
1042+
provider: 'github',
1043+
${hasCustomToken ? '// token: process.env.BUDDY_BOT_TOKEN,' : '// Uses GITHUB_TOKEN by default'}
1044+
},
1045+
dashboard: {
1046+
enabled: true,
1047+
title: 'Dependency Updates Dashboard',
1048+
// issueNumber: undefined, // Auto-generated
1049+
},
1050+
workflows: {
1051+
enabled: true,
1052+
outputDir: '.github/workflows',
1053+
templates: {
1054+
daily: true,
1055+
weekly: true,
1056+
monthly: true,
9831057
},
984-
dashboard: {
985-
enabled: true,
986-
pin: false,
987-
title: 'Dependency Updates Dashboard',
988-
issueNumber: undefined,
989-
},
990-
workflows: {
991-
enabled: true,
992-
outputDir: '.github/workflows',
993-
templates: {
994-
daily: true,
995-
weekly: true,
996-
monthly: true,
997-
},
998-
custom: [],
999-
},
1000-
packages: {
1001-
strategy: 'all',
1002-
ignore: [],
1003-
},
1004-
verbose: false,
1005-
}, null, 2)
1058+
custom: [],
1059+
},
1060+
packages: {
1061+
strategy: 'all',
1062+
ignore: [
1063+
// Add packages to ignore here
1064+
// Example: '@types/node', 'eslint'
1065+
],
1066+
},
1067+
verbose: false,
1068+
}
1069+
1070+
export default config
1071+
`
10061072

1007-
const configPath = 'buddy-bot.config.json'
1073+
const configPath = 'buddy-bot.config.ts'
10081074
fs.writeFileSync(configPath, configContent)
10091075
console.log(`✅ Created ${configPath} with your repository settings.`)
1010-
console.log(`💡 You can edit this file to customize Buddy Bot's behavior.\n`)
1076+
console.log(`💡 You can edit this file to customize Buddy Bot's behavior.`)
1077+
console.log(`🔧 The TypeScript config provides better IntelliSense and type safety.\n`)
10111078
}
10121079

10131080
/**
@@ -1770,26 +1837,27 @@ export async function showFinalInstructions(repoInfo: RepositoryInfo, hasCustomT
17701837
console.log(` - buddy-dashboard.yml (Dependency Dashboard Management)`)
17711838
console.log(` - buddy-update-check.yml (Auto-rebase PR checker)`)
17721839
console.log(` - buddy-update.yml (Scheduled dependency updates)`)
1773-
console.log(`📁 Configuration file: buddy-bot.config.json`)
1840+
console.log(`📁 Configuration file: buddy-bot.config.ts`)
17741841

17751842
console.log(`\n🚀 Next Steps:`)
17761843
console.log(`1. Review and commit the generated workflow files`)
1777-
console.log(` git add .github/workflows/ buddy-bot.config.json`)
1844+
console.log(` git add .github/workflows/ buddy-bot.config.ts`)
17781845
console.log(` git commit -m "Add Buddy Bot dependency management workflows"`)
17791846
console.log(` git push`)
17801847

17811848
if (hasCustomToken) {
1782-
console.log(`\n2. 🔑 Set up your Personal Access Token:`)
1783-
console.log(` - Go to: https://github.com/${repoInfo.owner}/${repoInfo.name}/settings/secrets/actions`)
1784-
console.log(` - Click "New repository secret"`)
1785-
console.log(` - Name: BUDDY_BOT_TOKEN`)
1786-
console.log(` - Value: your_personal_access_token`)
1787-
console.log(` - Click "Add secret"`)
1849+
console.log(`\n2. 🔑 Complete your token setup:`)
1850+
console.log(` ✅ Your Personal Access Token should be configured as:`)
1851+
console.log(` • Organization secret: BUDDY_BOT_TOKEN (recommended), or`)
1852+
console.log(` • Repository secret: BUDDY_BOT_TOKEN`)
1853+
console.log(` 💡 The workflows will automatically detect and use your token`)
17881854
}
17891855
else {
1790-
console.log(`\n2. ✅ Using default GITHUB_TOKEN (limited functionality)`)
1791-
console.log(` - Workflow file updates won't work`)
1792-
console.log(` - Consider upgrading to a Personal Access Token later`)
1856+
console.log(`\n2. ⚠️ Using default GITHUB_TOKEN (limited functionality):`)
1857+
console.log(` • Dependency updates: ✅ Will work`)
1858+
console.log(` • Dashboard creation: ✅ Will work`)
1859+
console.log(` • Workflow file updates: ❌ Won't work`)
1860+
console.log(` 💡 Consider setting up a Personal Access Token later for full functionality`)
17931861
}
17941862

17951863
console.log(`\n3. 🔧 Configure repository permissions:`)
@@ -1799,6 +1867,8 @@ export async function showFinalInstructions(repoInfo: RepositoryInfo, hasCustomT
17991867
console.log(` ✅ Check "Allow GitHub Actions to create and approve pull requests"`)
18001868
console.log(` - Click "Save"`)
18011869

1802-
console.log(`\n💡 Your workflows will now run automatically!`)
1870+
console.log(`\n🎉 Setup Complete!`)
1871+
console.log(`💡 Your workflows will now run automatically on schedule!`)
1872+
console.log(`📊 First dashboard update will appear within 24 hours`)
18031873
console.log(`🔗 Learn more: https://docs.github.com/en/actions`)
18041874
}

0 commit comments

Comments
 (0)