@launch77/cli 1.3.0 → 1.4.1

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.
Files changed (159) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cli.js +6 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/infrastructure/template-generator.d.ts +1 -1
  5. package/dist/infrastructure/template-generator.d.ts.map +1 -1
  6. package/dist/infrastructure/template.d.ts +5 -0
  7. package/dist/infrastructure/template.d.ts.map +1 -1
  8. package/dist/infrastructure/template.js +11 -0
  9. package/dist/infrastructure/template.js.map +1 -1
  10. package/dist/modules/app/commands/create-app.js +1 -1
  11. package/dist/modules/app/commands/create-app.js.map +1 -1
  12. package/dist/modules/app/commands/delete-app.js +1 -1
  13. package/dist/modules/app/commands/delete-app.js.map +1 -1
  14. package/dist/modules/app/services/app-svc.d.ts +1 -1
  15. package/dist/modules/app/services/app-svc.d.ts.map +1 -1
  16. package/dist/modules/app/services/manifest-svc.d.ts +1 -1
  17. package/dist/modules/app/services/manifest-svc.d.ts.map +1 -1
  18. package/dist/modules/catalog/config/catalog-config.test.js +1 -1
  19. package/dist/modules/catalog/config/catalog-config.test.js.map +1 -1
  20. package/dist/modules/git/commands/git-connect.js +2 -2
  21. package/dist/modules/git/commands/git-connect.js.map +1 -1
  22. package/dist/modules/git/errors/git-errors.d.ts +3 -0
  23. package/dist/modules/git/errors/git-errors.d.ts.map +1 -1
  24. package/dist/modules/git/errors/git-errors.js +6 -0
  25. package/dist/modules/git/errors/git-errors.js.map +1 -1
  26. package/dist/modules/git/index.d.ts +3 -1
  27. package/dist/modules/git/index.d.ts.map +1 -1
  28. package/dist/modules/git/index.js +6 -1
  29. package/dist/modules/git/index.js.map +1 -1
  30. package/dist/modules/git/services/git-service.d.ts +5 -0
  31. package/dist/modules/git/services/git-service.d.ts.map +1 -1
  32. package/dist/modules/git/services/git-service.js +11 -1
  33. package/dist/modules/git/services/git-service.js.map +1 -1
  34. package/dist/modules/plugin/commands/plugin-create.d.ts +3 -0
  35. package/dist/modules/plugin/commands/plugin-create.d.ts.map +1 -0
  36. package/dist/modules/plugin/commands/plugin-create.js +59 -0
  37. package/dist/modules/plugin/commands/plugin-create.js.map +1 -0
  38. package/dist/modules/plugin/commands/plugin-install.d.ts.map +1 -1
  39. package/dist/modules/plugin/commands/plugin-install.js +9 -24
  40. package/dist/modules/plugin/commands/plugin-install.js.map +1 -1
  41. package/dist/modules/plugin/errors/plugin-errors.d.ts +24 -1
  42. package/dist/modules/plugin/errors/plugin-errors.d.ts.map +1 -1
  43. package/dist/modules/plugin/errors/plugin-errors.js +79 -6
  44. package/dist/modules/plugin/errors/plugin-errors.js.map +1 -1
  45. package/dist/modules/plugin/index.d.ts +4 -2
  46. package/dist/modules/plugin/index.d.ts.map +1 -1
  47. package/dist/modules/plugin/index.js +4 -2
  48. package/dist/modules/plugin/index.js.map +1 -1
  49. package/dist/modules/plugin/lib/plugin-registry.d.ts +6 -12
  50. package/dist/modules/plugin/lib/plugin-registry.d.ts.map +1 -1
  51. package/dist/modules/plugin/lib/plugin-registry.js +13 -30
  52. package/dist/modules/plugin/lib/plugin-registry.js.map +1 -1
  53. package/dist/modules/plugin/lib/plugin-resolver.d.ts +76 -0
  54. package/dist/modules/plugin/lib/plugin-resolver.d.ts.map +1 -0
  55. package/dist/modules/plugin/lib/plugin-resolver.js +128 -0
  56. package/dist/modules/plugin/lib/plugin-resolver.js.map +1 -0
  57. package/dist/modules/plugin/lib/plugin-resolver.test.d.ts +2 -0
  58. package/dist/modules/plugin/lib/plugin-resolver.test.d.ts.map +1 -0
  59. package/dist/modules/plugin/lib/plugin-resolver.test.js +175 -0
  60. package/dist/modules/plugin/lib/plugin-resolver.test.js.map +1 -0
  61. package/dist/modules/plugin/services/plugin-create-service.d.ts +16 -0
  62. package/dist/modules/plugin/services/plugin-create-service.d.ts.map +1 -0
  63. package/dist/modules/plugin/services/plugin-create-service.js +47 -0
  64. package/dist/modules/plugin/services/plugin-create-service.js.map +1 -0
  65. package/dist/modules/plugin/services/plugin-svc.d.ts +29 -3
  66. package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -1
  67. package/dist/modules/plugin/services/plugin-svc.js +192 -17
  68. package/dist/modules/plugin/services/plugin-svc.js.map +1 -1
  69. package/dist/modules/plugin/services/plugin-svc.test.d.ts +2 -0
  70. package/dist/modules/plugin/services/plugin-svc.test.d.ts.map +1 -0
  71. package/dist/modules/plugin/services/plugin-svc.test.js +362 -0
  72. package/dist/modules/plugin/services/plugin-svc.test.js.map +1 -0
  73. package/dist/modules/release/commands/release-init.d.ts +3 -0
  74. package/dist/modules/release/commands/release-init.d.ts.map +1 -0
  75. package/dist/modules/release/commands/release-init.js +92 -0
  76. package/dist/modules/release/commands/release-init.js.map +1 -0
  77. package/dist/modules/release/errors/release-errors.d.ts +7 -0
  78. package/dist/modules/release/errors/release-errors.d.ts.map +1 -0
  79. package/dist/modules/release/errors/release-errors.js +13 -0
  80. package/dist/modules/release/errors/release-errors.js.map +1 -0
  81. package/dist/modules/release/index.d.ts +4 -0
  82. package/dist/modules/release/index.d.ts.map +1 -0
  83. package/dist/modules/release/index.js +7 -0
  84. package/dist/modules/release/index.js.map +1 -0
  85. package/dist/modules/release/services/release-service.d.ts +34 -0
  86. package/dist/modules/release/services/release-service.d.ts.map +1 -0
  87. package/dist/modules/release/services/release-service.js +154 -0
  88. package/dist/modules/release/services/release-service.js.map +1 -0
  89. package/dist/templates/plugin/README.md.hbs +39 -0
  90. package/dist/templates/plugin/package.json.hbs +34 -0
  91. package/dist/templates/plugin/plugin.json.hbs +7 -0
  92. package/dist/templates/plugin/src/generator.ts.hbs +64 -0
  93. package/dist/templates/plugin/templates/src/.gitkeep +0 -0
  94. package/dist/templates/plugin/tsconfig.json +10 -0
  95. package/dist/templates/plugin/tsup.config.ts +9 -0
  96. package/dist/templates/workspace/.github/workflows/ci.yml +8 -5
  97. package/dist/templates/workspace/package.json +3 -1
  98. package/dist/templates/workspace/turbo.json +5 -0
  99. package/dist/utils/launch77-context.d.ts +1 -1
  100. package/dist/utils/launch77-context.d.ts.map +1 -1
  101. package/dist/utils/launch77-context.js +25 -2
  102. package/dist/utils/launch77-context.js.map +1 -1
  103. package/dist/utils/launch77-validation.d.ts +1 -1
  104. package/dist/utils/launch77-validation.d.ts.map +1 -1
  105. package/dist/utils/string.d.ts +13 -0
  106. package/dist/utils/string.d.ts.map +1 -0
  107. package/dist/utils/string.js +18 -0
  108. package/dist/utils/string.js.map +1 -0
  109. package/package.json +6 -9
  110. package/src/cli.ts +7 -3
  111. package/src/infrastructure/template-generator.ts +1 -1
  112. package/src/infrastructure/template.ts +14 -0
  113. package/src/modules/app/commands/create-app.ts +1 -1
  114. package/src/modules/app/commands/delete-app.ts +1 -1
  115. package/src/modules/app/services/app-svc.ts +1 -1
  116. package/src/modules/app/services/manifest-svc.ts +1 -1
  117. package/src/modules/catalog/config/catalog-config.test.ts +1 -1
  118. package/src/modules/git/commands/git-connect.ts +2 -2
  119. package/src/modules/git/errors/git-errors.ts +7 -0
  120. package/src/modules/git/index.ts +8 -1
  121. package/src/modules/git/services/git-service.ts +12 -1
  122. package/src/modules/plugin/commands/plugin-create.ts +68 -0
  123. package/src/modules/plugin/commands/plugin-install.ts +9 -26
  124. package/src/modules/plugin/errors/plugin-errors.ts +87 -6
  125. package/src/modules/plugin/index.ts +4 -2
  126. package/src/modules/plugin/lib/plugin-registry.ts +14 -37
  127. package/src/modules/plugin/lib/plugin-resolver.test.ts +215 -0
  128. package/src/modules/plugin/lib/plugin-resolver.ts +160 -0
  129. package/src/modules/plugin/services/plugin-create-service.ts +69 -0
  130. package/src/modules/plugin/services/plugin-svc.test.ts +418 -0
  131. package/src/modules/plugin/services/plugin-svc.ts +217 -17
  132. package/src/modules/release/commands/release-init.ts +102 -0
  133. package/src/modules/release/errors/release-errors.ts +13 -0
  134. package/src/modules/release/index.ts +8 -0
  135. package/src/modules/release/services/release-service.ts +170 -0
  136. package/src/utils/launch77-context.ts +29 -3
  137. package/src/utils/launch77-validation.ts +1 -1
  138. package/src/utils/string.ts +17 -0
  139. package/templates/plugin/README.md.hbs +39 -0
  140. package/templates/plugin/package.json.hbs +34 -0
  141. package/templates/plugin/plugin.json.hbs +7 -0
  142. package/templates/plugin/src/generator.ts.hbs +64 -0
  143. package/templates/plugin/templates/src/.gitkeep +0 -0
  144. package/templates/plugin/tsconfig.json +10 -0
  145. package/templates/plugin/tsup.config.ts +9 -0
  146. package/templates/workspace/.github/workflows/ci.yml +8 -5
  147. package/templates/workspace/package.json +3 -1
  148. package/templates/workspace/turbo.json +5 -0
  149. package/tests/integration/cli.test.ts +25 -0
  150. package/tests/integration/setup.ts +20 -0
  151. package/vitest.config.ts +9 -0
  152. package/vitest.integration.config.ts +9 -0
  153. package/dist/modules/git/commands/git-setup-releases.d.ts +0 -3
  154. package/dist/modules/git/commands/git-setup-releases.d.ts.map +0 -1
  155. package/dist/modules/git/commands/git-setup-releases.js +0 -128
  156. package/dist/modules/git/commands/git-setup-releases.js.map +0 -1
  157. package/launch77-cli-1.2.0.tgz +0 -0
  158. package/src/modules/git/commands/git-setup-releases.ts +0 -148
  159. package/src/modules/plugin/lib/launch77-workspace.code-workspace +0 -14
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@{{workspaceName}}/plugin-{{pluginName}}",
3
+ "version": "1.0.0",
4
+ "description": "{{description}}",
5
+ "license": "UNLICENSED",
6
+ "private": true,
7
+ "type": "module",
8
+ "main": "dist/generator.js",
9
+ "bin": {
10
+ "generate": "./dist/generator.js"
11
+ },
12
+ "files": [
13
+ "dist/",
14
+ "templates/",
15
+ "plugin.json"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "dev": "tsup --watch",
20
+ "typecheck": "tsc --noEmit"
21
+ },
22
+ "dependencies": {
23
+ "@launch77/plugin-runtime": "^0.1.0",
24
+ "chalk": "^5.3.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^20.10.0",
28
+ "tsup": "^8.0.0",
29
+ "typescript": "^5.3.0"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ }
34
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "{{pluginName}}",
3
+ "version": "1.0.0",
4
+ "description": "{{description}}",
5
+ "pluginDependencies": {},
6
+ "libraryDependencies": {}
7
+ }
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+
3
+ import chalk from 'chalk'
4
+ import { StandardGenerator } from '@launch77/plugin-runtime'
5
+ import type { GeneratorContext } from '@launch77/plugin-runtime'
6
+
7
+ export class {{pluginNamePascal}}Generator extends StandardGenerator {
8
+ constructor(context: GeneratorContext) {
9
+ super(context)
10
+ }
11
+
12
+ protected async injectCode(): Promise<void> {
13
+ console.log(chalk.cyan('šŸ”§ Setting up {{pluginName}} plugin...\n'))
14
+
15
+ // TODO: Add your plugin's code injection logic here
16
+ // Examples:
17
+ // - Copy template files to the app
18
+ // - Modify package.json
19
+ // - Update configuration files
20
+
21
+ console.log(chalk.green(' āœ“ Plugin setup complete\n'))
22
+ }
23
+
24
+ protected showNextSteps(): void {
25
+ console.log(chalk.white('\n' + '─'.repeat(60) + '\n'))
26
+ console.log(chalk.cyan('šŸ“‹ {{pluginNamePascal}} Plugin Installed!\n'))
27
+ console.log(chalk.white('Next Steps:\n'))
28
+
29
+ console.log(chalk.gray('1. TODO: Add your first step'))
30
+ console.log(chalk.cyan(' npm run <command>\n'))
31
+
32
+ console.log(chalk.gray('2. TODO: Add your second step'))
33
+ console.log(chalk.cyan(' npm run <command>\n'))
34
+
35
+ console.log(chalk.white('Documentation:\n'))
36
+ console.log(chalk.gray('See README.md for detailed instructions.\n'))
37
+ }
38
+ }
39
+
40
+ // CLI entry point
41
+ async function main() {
42
+ const args = process.argv.slice(2)
43
+ const appPath = args.find((arg) => arg.startsWith('--appPath='))?.split('=')[1]
44
+ const appName = args.find((arg) => arg.startsWith('--appName='))?.split('=')[1]
45
+ const workspaceName = args.find((arg) => arg.startsWith('--workspaceName='))?.split('=')[1]
46
+ const pluginPath = args.find((arg) => arg.startsWith('--pluginPath='))?.split('=')[1]
47
+
48
+ if (!appPath || !appName || !workspaceName || !pluginPath) {
49
+ console.error(chalk.red('Error: Missing required arguments'))
50
+ console.error(chalk.gray('Usage: --appPath=<path> --appName=<name> --workspaceName=<name> --pluginPath=<path>'))
51
+ process.exit(1)
52
+ }
53
+
54
+ const generator = new {{pluginNamePascal}}Generator({ appPath, appName, workspaceName, pluginPath })
55
+ await generator.run()
56
+ }
57
+
58
+ if (import.meta.url === `file://${process.argv[1]}`) {
59
+ main().catch((error) => {
60
+ console.error(chalk.red('\nāŒ Error during plugin setup:'))
61
+ console.error(error)
62
+ process.exit(1)
63
+ })
64
+ }
File without changes
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "module": "ESNext",
7
+ "target": "ES2022"
8
+ },
9
+ "include": ["src/**/*"]
10
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/generator.ts'],
5
+ format: ['esm'],
6
+ dts: false,
7
+ clean: true,
8
+ shims: true,
9
+ })
@@ -31,20 +31,23 @@ jobs:
31
31
  cache: 'npm'
32
32
 
33
33
  - name: Install dependencies
34
- run: npm ci
34
+ run: npm install
35
35
 
36
36
  - name: Run linting
37
37
  run: npm run lint
38
38
 
39
- - name: Run type checking
40
- run: npm run typecheck
41
-
42
39
  - name: Build packages
43
40
  run: npm run build
44
41
 
42
+ - name: Run type checking
43
+ run: npm run typecheck
44
+
45
45
  - name: Run tests
46
46
  run: npm run test
47
47
 
48
+ - name: Run integration tests
49
+ run: npm run test:integration
50
+
48
51
  quality-checks:
49
52
  runs-on: ubuntu-latest
50
53
 
@@ -58,7 +61,7 @@ jobs:
58
61
  cache: 'npm'
59
62
 
60
63
  - name: Install dependencies
61
- run: npm ci
64
+ run: npm install
62
65
 
63
66
  - name: Check for dependency vulnerabilities
64
67
  run: npm audit --audit-level=high
@@ -13,12 +13,14 @@
13
13
  "dev": "turbo run dev",
14
14
  "build": "turbo run build",
15
15
  "test": "turbo run test",
16
+ "test:integration": "turbo run test:integration",
16
17
  "lint": "turbo run lint",
17
18
  "typecheck": "turbo run typecheck",
18
19
  "changeset": "changeset",
19
20
  "version-packages": "changeset version",
20
21
  "release": "turbo run build lint typecheck test && changeset publish",
21
- "prepare": "husky"
22
+ "prepare": "husky",
23
+ "clean": "rm -rf node_modules apps/*/node_modules libraries/*/node_modules plugins/*/node_modules app-templates/*/node_modules package-lock.json apps/*/package-lock.json libraries/*/package-lock.json plugins/*/package-lock.json app-templates/*/package-lock.json dist apps/*/dist libraries/*/dist plugins/*/dist app-templates/*/dist .next apps/*/.next .turbo apps/*/.turbo libraries/*/.turbo plugins/*/.turbo app-templates/*/.turbo build apps/*/build out apps/*/out coverage apps/*/coverage .cache *.log .eslintcache"
22
24
  },
23
25
  "devDependencies": {
24
26
  "@changesets/cli": "^2.29.8",
@@ -20,6 +20,11 @@
20
20
  "test": {
21
21
  "outputs": [],
22
22
  "dependsOn": ["build"]
23
+ },
24
+ "test:integration": {
25
+ "outputs": [],
26
+ "dependsOn": ["build"],
27
+ "cache": false
23
28
  }
24
29
  }
25
30
  }
@@ -0,0 +1,25 @@
1
+ import { describe, it, expect, beforeAll } from 'vitest'
2
+ import { existsSync } from 'fs'
3
+ import { runCli } from './setup.js'
4
+
5
+ describe('CLI Integration Tests', () => {
6
+ beforeAll(() => {
7
+ if (!existsSync('./dist/cli.js')) {
8
+ throw new Error('CLI not built. Run `npm run build` first.')
9
+ }
10
+ })
11
+
12
+ it('should display version', async () => {
13
+ const { stdout, exitCode } = await runCli(['--version'])
14
+
15
+ expect(exitCode).toBe(0)
16
+ expect(stdout).toMatch(/\d+\.\d+\.\d+/)
17
+ })
18
+
19
+ it('should display help', async () => {
20
+ const { stdout, exitCode } = await runCli(['--help'])
21
+
22
+ expect(exitCode).toBe(0)
23
+ expect(stdout).toContain('launch77')
24
+ })
25
+ })
@@ -0,0 +1,20 @@
1
+ import { execa } from 'execa'
2
+ import { fileURLToPath } from 'url'
3
+ import { dirname, join } from 'path'
4
+
5
+ const __dirname = dirname(fileURLToPath(import.meta.url))
6
+ const CLI_PATH = join(__dirname, '../../dist/cli.js')
7
+
8
+ export async function runCli(args: string[], options?: { cwd?: string }) {
9
+ const result = await execa('node', [CLI_PATH, ...args], {
10
+ reject: false,
11
+ cwd: options?.cwd,
12
+ env: { ...process.env, CI: 'true' },
13
+ })
14
+
15
+ return {
16
+ stdout: result.stdout,
17
+ stderr: result.stderr,
18
+ exitCode: result.exitCode ?? 0,
19
+ }
20
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ['src/**/*.test.ts'],
6
+ testTimeout: 10000,
7
+ hookTimeout: 10000,
8
+ },
9
+ })
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ['tests/integration/**/*.test.ts'],
6
+ testTimeout: 30000,
7
+ hookTimeout: 60000,
8
+ },
9
+ })
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function gitSetupReleasesCommand(): Command;
3
- //# sourceMappingURL=git-setup-releases.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"git-setup-releases.d.ts","sourceRoot":"","sources":["../../../../src/modules/git/commands/git-setup-releases.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAanC,wBAAgB,uBAAuB,IAAI,OAAO,CAqIjD"}
@@ -1,128 +0,0 @@
1
- import chalk from 'chalk';
2
- import { Command } from 'commander';
3
- import { password, confirm } from '@inquirer/prompts';
4
- import ora from 'ora';
5
- import { detectLaunch77Context } from '../../../utils/launch77-context.js';
6
- import { GitHubCLINotInstalledError, GitHubNotAuthenticatedError, NotInWorkspaceError } from '../errors/git-errors.js';
7
- import { GitHubService } from '../services/github-service.js';
8
- import { GitService } from '../services/git-service.js';
9
- export function gitSetupReleasesCommand() {
10
- return new Command('git:setup-releases')
11
- .description('Configure GitHub RELEASE_TOKEN for automated release PRs')
12
- .option('--token <token>', 'Personal Access Token (for automation)')
13
- .action(async (options) => {
14
- console.log(chalk.blue('\nšŸ” Setting up GitHub release automation...\n'));
15
- const cwd = process.cwd();
16
- const githubService = new GitHubService();
17
- const gitService = new GitService();
18
- try {
19
- // 1. Verify we're in a workspace root
20
- const context = await detectLaunch77Context(cwd);
21
- if (!context.isValid || context.locationType !== 'workspace-root') {
22
- throw new NotInWorkspaceError(cwd);
23
- }
24
- // 2. Verify prerequisites
25
- const spinner = ora('Checking prerequisites...').start();
26
- await githubService.verifyPrerequisites();
27
- spinner.succeed('Prerequisites verified');
28
- // 3. Check if repository has a remote
29
- const hasOrigin = await gitService.hasRemote(context.workspaceRoot);
30
- if (!hasOrigin) {
31
- console.error(chalk.red('\nāŒ This workspace is not connected to a GitHub repository\n'));
32
- console.log(chalk.gray(` Connect to GitHub first: ${chalk.cyan('launch77 git:connect')}\n`));
33
- process.exit(1);
34
- }
35
- // 4. Get current repository information
36
- const repoSpinner = ora('Detecting repository...').start();
37
- const { owner, repo } = await githubService.getCurrentRepository(context.workspaceRoot);
38
- repoSpinner.succeed(`Repository: ${owner}/${repo}`);
39
- // 5. Explain what RELEASE_TOKEN is
40
- console.log(chalk.cyan('\nšŸ“‹ About RELEASE_TOKEN:\n'));
41
- console.log(chalk.white('The RELEASE_TOKEN is a GitHub Personal Access Token (PAT) that allows'));
42
- console.log(chalk.white('the Changesets action to create Pull Requests for version updates.\n'));
43
- console.log(chalk.white('Why is this needed?'));
44
- console.log(chalk.gray(' • The default GITHUB_TOKEN has limited permissions'));
45
- console.log(chalk.gray(' • Creating PRs that trigger CI requires a PAT'));
46
- console.log(chalk.gray(' • This enables automated release workflows\n'));
47
- console.log(chalk.white('Required permissions:'));
48
- console.log(chalk.gray(' • Contents: Read and write'));
49
- console.log(chalk.gray(' • Pull requests: Read and write\n'));
50
- // 6. Provide link to create PAT
51
- const tokenUrl = 'https://github.com/settings/personal-access-tokens/new';
52
- console.log(chalk.cyan('šŸ”— Create your token:'));
53
- console.log(chalk.gray(` ${chalk.cyan(tokenUrl)}`));
54
- console.log(chalk.gray(` Name: Launch77 Release Token`));
55
- console.log(chalk.gray(` Permissions: Contents (Read and write), Pull requests (Read and write)\n`));
56
- // 7. Get the token (from option or prompt)
57
- let token;
58
- if (options.token) {
59
- token = options.token;
60
- }
61
- else {
62
- token = await password({
63
- message: 'Paste your Personal Access Token (PAT):',
64
- mask: '*',
65
- validate: (value) => {
66
- if (!value || value.trim().length === 0) {
67
- return 'Token cannot be empty';
68
- }
69
- // GitHub PATs start with specific prefixes
70
- if (!value.startsWith('ghp_') && !value.startsWith('github_pat_')) {
71
- return 'Invalid token format. GitHub PATs should start with "ghp_" or "github_pat_"';
72
- }
73
- return true;
74
- },
75
- });
76
- }
77
- // 8. Confirm if token already might exist
78
- console.log(chalk.yellow('\n⚠ Note: This will overwrite any existing RELEASE_TOKEN secret\n'));
79
- const shouldContinue = await confirm({
80
- message: 'Continue and set RELEASE_TOKEN?',
81
- default: true,
82
- });
83
- if (!shouldContinue) {
84
- console.log(chalk.green('\nāœ… No changes made.\n'));
85
- process.exit(0);
86
- }
87
- // 9. Set the repository secret
88
- const setSpinner = ora('Setting RELEASE_TOKEN secret...').start();
89
- try {
90
- await githubService.setRepositorySecret(owner, repo, 'RELEASE_TOKEN', token);
91
- setSpinner.succeed('RELEASE_TOKEN configured successfully!');
92
- // Success message
93
- console.log(chalk.green('\nāœ… Release automation is ready!\n'));
94
- console.log(chalk.white('What happens now:'));
95
- console.log(chalk.gray(' • When you push to main, CI runs as usual'));
96
- console.log(chalk.gray(' • Changesets detects version changes'));
97
- console.log(chalk.gray(' • A "Version Packages" PR is created automatically'));
98
- console.log(chalk.gray(' • Merge the PR to publish your packages\n'));
99
- console.log(chalk.cyan('šŸ“š Learn more:'));
100
- console.log(chalk.gray(` ${chalk.cyan('https://github.com/changesets/changesets')}\n`));
101
- }
102
- catch (error) {
103
- setSpinner.fail('Failed to set RELEASE_TOKEN');
104
- throw error;
105
- }
106
- }
107
- catch (error) {
108
- if (error instanceof GitHubCLINotInstalledError) {
109
- console.error(chalk.red(`\nāŒ ${error.message}\n`));
110
- console.log(chalk.gray(` Install with: ${chalk.cyan('brew install gh')}\n`));
111
- console.log(chalk.gray(` Or visit: ${chalk.cyan('https://cli.github.com/')}\n`));
112
- process.exit(1);
113
- }
114
- if (error instanceof GitHubNotAuthenticatedError) {
115
- console.error(chalk.red(`\nāŒ ${error.message}\n`));
116
- console.log(chalk.gray(` Authenticate with: ${chalk.cyan('gh auth login')}\n`));
117
- process.exit(1);
118
- }
119
- if (error instanceof NotInWorkspaceError) {
120
- console.error(chalk.red(`\nāŒ ${error.message}\n`));
121
- console.log(chalk.gray(` This command must be run from a Launch77 workspace root directory\n`));
122
- process.exit(1);
123
- }
124
- throw error;
125
- }
126
- });
127
- }
128
- //# sourceMappingURL=git-setup-releases.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"git-setup-releases.js","sourceRoot":"","sources":["../../../../src/modules/git/commands/git-setup-releases.ts"],"names":[],"mappings":"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"}
Binary file
@@ -1,148 +0,0 @@
1
- import chalk from 'chalk'
2
- import { Command } from 'commander'
3
- import { password, confirm } from '@inquirer/prompts'
4
- import ora from 'ora'
5
-
6
- import { detectLaunch77Context } from '../../../utils/launch77-context.js'
7
- import { GitHubCLINotInstalledError, GitHubNotAuthenticatedError, NotInWorkspaceError } from '../errors/git-errors.js'
8
- import { GitHubService } from '../services/github-service.js'
9
- import { GitService } from '../services/git-service.js'
10
-
11
- interface SetupReleasesOptions {
12
- token?: string
13
- }
14
-
15
- export function gitSetupReleasesCommand(): Command {
16
- return new Command('git:setup-releases')
17
- .description('Configure GitHub RELEASE_TOKEN for automated release PRs')
18
- .option('--token <token>', 'Personal Access Token (for automation)')
19
- .action(async (options: SetupReleasesOptions) => {
20
- console.log(chalk.blue('\nšŸ” Setting up GitHub release automation...\n'))
21
-
22
- const cwd = process.cwd()
23
- const githubService = new GitHubService()
24
- const gitService = new GitService()
25
-
26
- try {
27
- // 1. Verify we're in a workspace root
28
- const context = await detectLaunch77Context(cwd)
29
- if (!context.isValid || context.locationType !== 'workspace-root') {
30
- throw new NotInWorkspaceError(cwd)
31
- }
32
-
33
- // 2. Verify prerequisites
34
- const spinner = ora('Checking prerequisites...').start()
35
-
36
- await githubService.verifyPrerequisites()
37
-
38
- spinner.succeed('Prerequisites verified')
39
-
40
- // 3. Check if repository has a remote
41
- const hasOrigin = await gitService.hasRemote(context.workspaceRoot)
42
- if (!hasOrigin) {
43
- console.error(chalk.red('\nāŒ This workspace is not connected to a GitHub repository\n'))
44
- console.log(chalk.gray(` Connect to GitHub first: ${chalk.cyan('launch77 git:connect')}\n`))
45
- process.exit(1)
46
- }
47
-
48
- // 4. Get current repository information
49
- const repoSpinner = ora('Detecting repository...').start()
50
- const { owner, repo } = await githubService.getCurrentRepository(context.workspaceRoot)
51
- repoSpinner.succeed(`Repository: ${owner}/${repo}`)
52
-
53
- // 5. Explain what RELEASE_TOKEN is
54
- console.log(chalk.cyan('\nšŸ“‹ About RELEASE_TOKEN:\n'))
55
- console.log(chalk.white('The RELEASE_TOKEN is a GitHub Personal Access Token (PAT) that allows'))
56
- console.log(chalk.white('the Changesets action to create Pull Requests for version updates.\n'))
57
- console.log(chalk.white('Why is this needed?'))
58
- console.log(chalk.gray(' • The default GITHUB_TOKEN has limited permissions'))
59
- console.log(chalk.gray(' • Creating PRs that trigger CI requires a PAT'))
60
- console.log(chalk.gray(' • This enables automated release workflows\n'))
61
- console.log(chalk.white('Required permissions:'))
62
- console.log(chalk.gray(' • Contents: Read and write'))
63
- console.log(chalk.gray(' • Pull requests: Read and write\n'))
64
-
65
- // 6. Provide link to create PAT
66
- const tokenUrl = 'https://github.com/settings/personal-access-tokens/new'
67
- console.log(chalk.cyan('šŸ”— Create your token:'))
68
- console.log(chalk.gray(` ${chalk.cyan(tokenUrl)}`))
69
- console.log(chalk.gray(` Name: Launch77 Release Token`))
70
- console.log(chalk.gray(` Permissions: Contents (Read and write), Pull requests (Read and write)\n`))
71
-
72
- // 7. Get the token (from option or prompt)
73
- let token: string
74
- if (options.token) {
75
- token = options.token
76
- } else {
77
- token = await password({
78
- message: 'Paste your Personal Access Token (PAT):',
79
- mask: '*',
80
- validate: (value) => {
81
- if (!value || value.trim().length === 0) {
82
- return 'Token cannot be empty'
83
- }
84
- // GitHub PATs start with specific prefixes
85
- if (!value.startsWith('ghp_') && !value.startsWith('github_pat_')) {
86
- return 'Invalid token format. GitHub PATs should start with "ghp_" or "github_pat_"'
87
- }
88
- return true
89
- },
90
- })
91
- }
92
-
93
- // 8. Confirm if token already might exist
94
- console.log(chalk.yellow('\n⚠ Note: This will overwrite any existing RELEASE_TOKEN secret\n'))
95
- const shouldContinue = await confirm({
96
- message: 'Continue and set RELEASE_TOKEN?',
97
- default: true,
98
- })
99
-
100
- if (!shouldContinue) {
101
- console.log(chalk.green('\nāœ… No changes made.\n'))
102
- process.exit(0)
103
- }
104
-
105
- // 9. Set the repository secret
106
- const setSpinner = ora('Setting RELEASE_TOKEN secret...').start()
107
-
108
- try {
109
- await githubService.setRepositorySecret(owner, repo, 'RELEASE_TOKEN', token)
110
- setSpinner.succeed('RELEASE_TOKEN configured successfully!')
111
-
112
- // Success message
113
- console.log(chalk.green('\nāœ… Release automation is ready!\n'))
114
- console.log(chalk.white('What happens now:'))
115
- console.log(chalk.gray(' • When you push to main, CI runs as usual'))
116
- console.log(chalk.gray(' • Changesets detects version changes'))
117
- console.log(chalk.gray(' • A "Version Packages" PR is created automatically'))
118
- console.log(chalk.gray(' • Merge the PR to publish your packages\n'))
119
- console.log(chalk.cyan('šŸ“š Learn more:'))
120
- console.log(chalk.gray(` ${chalk.cyan('https://github.com/changesets/changesets')}\n`))
121
- } catch (error) {
122
- setSpinner.fail('Failed to set RELEASE_TOKEN')
123
- throw error
124
- }
125
- } catch (error) {
126
- if (error instanceof GitHubCLINotInstalledError) {
127
- console.error(chalk.red(`\nāŒ ${error.message}\n`))
128
- console.log(chalk.gray(` Install with: ${chalk.cyan('brew install gh')}\n`))
129
- console.log(chalk.gray(` Or visit: ${chalk.cyan('https://cli.github.com/')}\n`))
130
- process.exit(1)
131
- }
132
-
133
- if (error instanceof GitHubNotAuthenticatedError) {
134
- console.error(chalk.red(`\nāŒ ${error.message}\n`))
135
- console.log(chalk.gray(` Authenticate with: ${chalk.cyan('gh auth login')}\n`))
136
- process.exit(1)
137
- }
138
-
139
- if (error instanceof NotInWorkspaceError) {
140
- console.error(chalk.red(`\nāŒ ${error.message}\n`))
141
- console.log(chalk.gray(` This command must be run from a Launch77 workspace root directory\n`))
142
- process.exit(1)
143
- }
144
-
145
- throw error
146
- }
147
- })
148
- }
@@ -1,14 +0,0 @@
1
- {
2
- "folders": [
3
- {
4
- "path": "../../../../../.."
5
- },
6
- {
7
- "path": "../../../../../../../launch77"
8
- },
9
- {
10
- "path": "../../../../../../../launch-workspaces/fostersauce"
11
- }
12
- ],
13
- "settings": {}
14
- }