infra-kit 0.1.55 → 0.1.57
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/dist/cli.js +14 -14
- package/dist/cli.js.map +4 -4
- package/dist/mcp.js +14 -14
- package/dist/mcp.js.map +4 -4
- package/package.json +1 -1
- package/src/commands/release-create/index.ts +1 -0
- package/src/commands/release-create/release-create.ts +106 -0
- package/src/commands/release-create-batch/index.ts +1 -0
- package/src/commands/release-create-batch/release-create-batch.ts +114 -0
- package/src/entry/cli.ts +25 -4
- package/src/integrations/gh/gh-release-prs/gh-release-prs.ts +15 -2
- package/src/integrations/jira/api.ts +2 -2
- package/src/lib/load-env/index.ts +1 -0
- package/src/lib/release-utils/index.ts +1 -0
- package/src/lib/release-utils/release-utils.ts +66 -0
- package/src/mcp/tools/index.ts +4 -2
- package/src/commands/gh-release-create/gh-release-create.ts +0 -169
- package/src/commands/gh-release-create/index.ts +0 -1
- /package/src/lib/{load-env.ts → load-env/load-env.ts} +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import confirm from '@inquirer/confirm'
|
|
2
|
+
import process from 'node:process'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import { $, question } from 'zx'
|
|
5
|
+
|
|
6
|
+
import { loadJiraConfig } from 'src/integrations/jira'
|
|
7
|
+
import { logger } from 'src/lib/logger'
|
|
8
|
+
import { createSingleRelease, prepareGitForRelease } from 'src/lib/release-utils'
|
|
9
|
+
import type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'
|
|
10
|
+
|
|
11
|
+
interface ReleaseCreateArgs extends RequiredConfirmedOptionArg {
|
|
12
|
+
version: string
|
|
13
|
+
description?: string
|
|
14
|
+
checkout?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a single release branch for the specified version
|
|
19
|
+
* Includes Jira version creation and GitHub release branch creation
|
|
20
|
+
*/
|
|
21
|
+
export const releaseCreate = async (args: ReleaseCreateArgs): Promise<ToolsExecutionResult> => {
|
|
22
|
+
const { version: inputVersion, description, confirmedCommand, checkout = true } = args
|
|
23
|
+
|
|
24
|
+
let version = inputVersion
|
|
25
|
+
|
|
26
|
+
// Load Jira config - it is now mandatory
|
|
27
|
+
const jiraConfig = await loadJiraConfig()
|
|
28
|
+
|
|
29
|
+
if (!version) {
|
|
30
|
+
version = await question('Enter version (e.g. 1.2.5): ')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Validate input
|
|
34
|
+
if (!version || version.trim() === '') {
|
|
35
|
+
logger.error('No version provided. Exiting...')
|
|
36
|
+
process.exit(1)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const trimmedVersion = version.trim()
|
|
40
|
+
|
|
41
|
+
const answer = confirmedCommand
|
|
42
|
+
? true
|
|
43
|
+
: await confirm({
|
|
44
|
+
message: `Are you sure you want to create release branch for version ${trimmedVersion}?`,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
if (!answer) {
|
|
48
|
+
logger.info('Operation cancelled. Exiting...')
|
|
49
|
+
process.exit(0)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
await prepareGitForRelease()
|
|
53
|
+
|
|
54
|
+
// Create the release
|
|
55
|
+
const release = await createSingleRelease(trimmedVersion, jiraConfig, description)
|
|
56
|
+
|
|
57
|
+
logger.info(`✅ Successfully created release: v${trimmedVersion}`)
|
|
58
|
+
logger.info(`🔗 GitHub PR: ${release.prUrl}`)
|
|
59
|
+
logger.info(`🔗 Jira Version: ${release.jiraVersionUrl}`)
|
|
60
|
+
|
|
61
|
+
// Checkout to the created branch by default
|
|
62
|
+
if (checkout) {
|
|
63
|
+
$.quiet = true
|
|
64
|
+
await $`git switch ${release.branchName}`
|
|
65
|
+
$.quiet = false
|
|
66
|
+
|
|
67
|
+
logger.info(`🔄 Switched to branch ${release.branchName}`)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const structuredContent = {
|
|
71
|
+
version: trimmedVersion,
|
|
72
|
+
branchName: release.branchName,
|
|
73
|
+
prUrl: release.prUrl,
|
|
74
|
+
jiraVersionUrl: release.jiraVersionUrl,
|
|
75
|
+
isCheckedOut: checkout,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'text',
|
|
82
|
+
text: JSON.stringify(structuredContent, null, 2),
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
structuredContent,
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// MCP Tool Registration
|
|
90
|
+
export const releaseCreateMcpTool = {
|
|
91
|
+
name: 'release-create',
|
|
92
|
+
description: 'Create a single release branch for specified version with Jira version creation',
|
|
93
|
+
inputSchema: {
|
|
94
|
+
version: z.string().describe('Version to create (e.g., "1.2.5")'),
|
|
95
|
+
description: z.string().optional().describe('Optional description for the Jira version'),
|
|
96
|
+
checkout: z.boolean().optional().default(true).describe('Checkout to the created branch (default: true)'),
|
|
97
|
+
},
|
|
98
|
+
outputSchema: {
|
|
99
|
+
version: z.string().describe('Version number'),
|
|
100
|
+
branchName: z.string().describe('Release branch name'),
|
|
101
|
+
prUrl: z.string().describe('GitHub PR URL'),
|
|
102
|
+
jiraVersionUrl: z.string().describe('Jira version URL'),
|
|
103
|
+
isCheckedOut: z.boolean().describe('Whether the branch was checked out'),
|
|
104
|
+
},
|
|
105
|
+
handler: releaseCreate,
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { releaseCreateBatch, releaseCreateBatchMcpTool } from './release-create-batch'
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import confirm from '@inquirer/confirm'
|
|
2
|
+
import process from 'node:process'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import { question } from 'zx'
|
|
5
|
+
|
|
6
|
+
import { loadJiraConfig } from 'src/integrations/jira'
|
|
7
|
+
import { logger } from 'src/lib/logger'
|
|
8
|
+
import { createSingleRelease, prepareGitForRelease } from 'src/lib/release-utils'
|
|
9
|
+
import type { ReleaseCreationResult } from 'src/lib/release-utils'
|
|
10
|
+
import type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'
|
|
11
|
+
|
|
12
|
+
interface ReleaseCreateBatchArgs extends RequiredConfirmedOptionArg {
|
|
13
|
+
versions: string
|
|
14
|
+
description?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create multiple release branches for the specified versions
|
|
19
|
+
* Includes Jira version creation and GitHub release branch creation for each version
|
|
20
|
+
*/
|
|
21
|
+
export const releaseCreateBatch = async (args: ReleaseCreateBatchArgs): Promise<ToolsExecutionResult> => {
|
|
22
|
+
const { versions: inputVersions, description, confirmedCommand } = args
|
|
23
|
+
|
|
24
|
+
let versionInput = inputVersions
|
|
25
|
+
|
|
26
|
+
// Load Jira config - it is now mandatory
|
|
27
|
+
const jiraConfig = await loadJiraConfig()
|
|
28
|
+
|
|
29
|
+
if (!versionInput) {
|
|
30
|
+
versionInput = await question('Enter versions by comma (e.g. 1.2.5, 1.2.6): ')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const versionsList = versionInput.split(',').map((version) => version.trim())
|
|
34
|
+
|
|
35
|
+
// Validate input
|
|
36
|
+
if (versionsList.length === 0) {
|
|
37
|
+
logger.error('No versions provided. Exiting...')
|
|
38
|
+
process.exit(1)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Inform user if they only provided one version
|
|
42
|
+
if (versionsList.length === 1) {
|
|
43
|
+
logger.warn('💡 You are creating only one release. Consider using "create-release" command for single releases.')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const answer = confirmedCommand
|
|
47
|
+
? true
|
|
48
|
+
: await confirm({
|
|
49
|
+
message: `Are you sure you want to create release branches for these versions: ${versionsList.join(', ')}?`,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
if (!answer) {
|
|
53
|
+
logger.info('Operation cancelled. Exiting...')
|
|
54
|
+
process.exit(0)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
await prepareGitForRelease()
|
|
58
|
+
|
|
59
|
+
const releases: ReleaseCreationResult[] = []
|
|
60
|
+
|
|
61
|
+
for (const version of versionsList) {
|
|
62
|
+
// Create each release
|
|
63
|
+
const release = await createSingleRelease(version, jiraConfig, description)
|
|
64
|
+
|
|
65
|
+
releases.push(release)
|
|
66
|
+
|
|
67
|
+
logger.info(`✅ Successfully created release: v${version}`)
|
|
68
|
+
logger.info(`🔗 GitHub PR: ${release.prUrl}`)
|
|
69
|
+
logger.info(`🔗 Jira Version: ${release.jiraVersionUrl}\n`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
logger.info(`${versionsList.length} release branches were created successfully.`)
|
|
73
|
+
|
|
74
|
+
const structuredContent = {
|
|
75
|
+
createdBranches: versionsList.map((version) => `release/v${version}`),
|
|
76
|
+
branchCount: versionsList.length,
|
|
77
|
+
releases,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
content: [
|
|
82
|
+
{
|
|
83
|
+
type: 'text',
|
|
84
|
+
text: JSON.stringify(structuredContent, null, 2),
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
structuredContent,
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// MCP Tool Registration
|
|
92
|
+
export const releaseCreateBatchMcpTool = {
|
|
93
|
+
name: 'release-create-batch',
|
|
94
|
+
description: 'Create multiple release branches for specified versions with Jira version creation (batch operation)',
|
|
95
|
+
inputSchema: {
|
|
96
|
+
versions: z.string().describe('Comma-separated list of versions to create (e.g., "1.2.5, 1.2.6")'),
|
|
97
|
+
description: z.string().optional().describe('Optional description for the Jira versions'),
|
|
98
|
+
},
|
|
99
|
+
outputSchema: {
|
|
100
|
+
createdBranches: z.array(z.string()).describe('List of created release branches'),
|
|
101
|
+
branchCount: z.number().describe('Number of branches created'),
|
|
102
|
+
releases: z
|
|
103
|
+
.array(
|
|
104
|
+
z.object({
|
|
105
|
+
version: z.string().describe('Version number'),
|
|
106
|
+
branchName: z.string().describe('Release branch name'),
|
|
107
|
+
prUrl: z.string().describe('GitHub PR URL'),
|
|
108
|
+
jiraVersionUrl: z.string().describe('Jira version URL'),
|
|
109
|
+
}),
|
|
110
|
+
)
|
|
111
|
+
.describe('Detailed information for each created release with URLs'),
|
|
112
|
+
},
|
|
113
|
+
handler: releaseCreateBatch,
|
|
114
|
+
}
|
package/src/entry/cli.ts
CHANGED
|
@@ -2,10 +2,11 @@ import { Command } from 'commander'
|
|
|
2
2
|
|
|
3
3
|
// Commands
|
|
4
4
|
import { ghMergeDev } from 'src/commands/gh-merge-dev'
|
|
5
|
-
import { ghReleaseCreate } from 'src/commands/gh-release-create'
|
|
6
5
|
import { ghReleaseDeliver } from 'src/commands/gh-release-deliver'
|
|
7
6
|
import { ghReleaseDeploy } from 'src/commands/gh-release-deploy'
|
|
8
7
|
import { ghReleaseList } from 'src/commands/gh-release-list'
|
|
8
|
+
import { releaseCreate } from 'src/commands/release-create'
|
|
9
|
+
import { releaseCreateBatch } from 'src/commands/release-create-batch'
|
|
9
10
|
import { worktreesAdd } from 'src/commands/worktrees-add'
|
|
10
11
|
import { worktreesList } from 'src/commands/worktrees-list'
|
|
11
12
|
import { worktreesRemove } from 'src/commands/worktrees-remove'
|
|
@@ -37,12 +38,32 @@ program
|
|
|
37
38
|
|
|
38
39
|
program
|
|
39
40
|
.command('release-create')
|
|
40
|
-
.description('Create
|
|
41
|
+
.description('Create a single release branch')
|
|
42
|
+
.option('-v, --version <version>', 'Specify the version to create, e.g. 1.2.5')
|
|
43
|
+
.option('-d, --description <description>', 'Optional description for the Jira version')
|
|
44
|
+
.option('-y, --yes', 'Skip confirmation prompt')
|
|
45
|
+
.option('--no-checkout', 'Do not checkout the created branch after creation (checkout is default)')
|
|
46
|
+
.action(async (options) => {
|
|
47
|
+
await releaseCreate({
|
|
48
|
+
version: options.version,
|
|
49
|
+
description: options.description,
|
|
50
|
+
confirmedCommand: options.yes,
|
|
51
|
+
checkout: options.checkout,
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
program
|
|
56
|
+
.command('release-create-batch')
|
|
57
|
+
.description('Create multiple release branches (batch operation)')
|
|
41
58
|
.option('-v, --versions <versions>', 'Specify the versions to create by comma, e.g. 1.2.5, 1.2.6')
|
|
59
|
+
.option('-d, --description <description>', 'Optional description for the Jira versions')
|
|
42
60
|
.option('-y, --yes', 'Skip confirmation prompt')
|
|
43
|
-
.option('-c, --checkout', 'Checkout the created branch after creation (only works when creating a single branch)')
|
|
44
61
|
.action(async (options) => {
|
|
45
|
-
await
|
|
62
|
+
await releaseCreateBatch({
|
|
63
|
+
versions: options.versions,
|
|
64
|
+
description: options.description,
|
|
65
|
+
confirmedCommand: options.yes,
|
|
66
|
+
})
|
|
46
67
|
})
|
|
47
68
|
|
|
48
69
|
program
|
|
@@ -40,11 +40,22 @@ export const getReleasePRs = async (): Promise<string[]> => {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
interface CreateReleaseBranchArgs {
|
|
44
|
+
version: string
|
|
45
|
+
jiraVersionUrl: string
|
|
46
|
+
}
|
|
47
|
+
|
|
43
48
|
// Function to create a release branch
|
|
44
|
-
export const createReleaseBranch = async (
|
|
49
|
+
export const createReleaseBranch = async (
|
|
50
|
+
args: CreateReleaseBranchArgs,
|
|
51
|
+
): Promise<{ branchName: string; prUrl: string }> => {
|
|
52
|
+
const { version, jiraVersionUrl } = args
|
|
53
|
+
|
|
45
54
|
const branchName = `release/v${version}`
|
|
46
55
|
|
|
47
56
|
try {
|
|
57
|
+
$.quiet = true
|
|
58
|
+
|
|
48
59
|
await $`git switch dev`
|
|
49
60
|
await $`git pull origin dev`
|
|
50
61
|
await $`git checkout -b ${branchName}`
|
|
@@ -54,12 +65,14 @@ export const createReleaseBranch = async (version: string): Promise<{ branchName
|
|
|
54
65
|
|
|
55
66
|
// Create PR and capture URL
|
|
56
67
|
const prResult =
|
|
57
|
-
await $`gh pr create --title "Release v${version}" --body "
|
|
68
|
+
await $`gh pr create --title "Release v${version}" --body "${jiraVersionUrl} \n" --base dev --head ${branchName}`
|
|
58
69
|
|
|
59
70
|
const prLink = prResult.stdout.trim()
|
|
60
71
|
|
|
61
72
|
await $`git switch dev`
|
|
62
73
|
|
|
74
|
+
$.quiet = false
|
|
75
|
+
|
|
63
76
|
return {
|
|
64
77
|
branchName,
|
|
65
78
|
prUrl: prLink,
|
|
@@ -36,8 +36,8 @@ export const createJiraVersion = async (
|
|
|
36
36
|
projectId: params.projectId || projectId,
|
|
37
37
|
description: params.description || '',
|
|
38
38
|
// releaseDate,
|
|
39
|
-
released: params.released
|
|
40
|
-
archived: params.archived
|
|
39
|
+
released: params.released || false,
|
|
40
|
+
archived: params.archived || false,
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// logger.info(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { loadEnvFromGitRoot } from './load-env'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createSingleRelease, prepareGitForRelease, type ReleaseCreationResult } from './release-utils'
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { $ } from 'zx'
|
|
2
|
+
|
|
3
|
+
import { createReleaseBranch } from 'src/integrations/gh'
|
|
4
|
+
import { createJiraVersion } from 'src/integrations/jira'
|
|
5
|
+
import type { JiraConfig } from 'src/integrations/jira'
|
|
6
|
+
|
|
7
|
+
export interface ReleaseCreationResult {
|
|
8
|
+
version: string
|
|
9
|
+
branchName: string
|
|
10
|
+
prUrl: string
|
|
11
|
+
jiraVersionUrl: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Prepare git repository for release creation
|
|
16
|
+
* Fetches latest changes, switches to dev branch, and pulls latest
|
|
17
|
+
*/
|
|
18
|
+
export const prepareGitForRelease = async (): Promise<void> => {
|
|
19
|
+
$.quiet = true
|
|
20
|
+
|
|
21
|
+
await $`git fetch origin`
|
|
22
|
+
await $`git switch dev`
|
|
23
|
+
await $`git pull origin dev`
|
|
24
|
+
|
|
25
|
+
$.quiet = false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Create a single release by creating both Jira version and GitHub release branch
|
|
30
|
+
* @param version - Version number (e.g., "1.2.5")
|
|
31
|
+
* @param jiraConfig - Jira configuration object
|
|
32
|
+
* @param description - Optional description for the Jira version
|
|
33
|
+
* @returns Release creation result with URLs and metadata
|
|
34
|
+
*/
|
|
35
|
+
export const createSingleRelease = async (
|
|
36
|
+
version: string,
|
|
37
|
+
jiraConfig: JiraConfig,
|
|
38
|
+
description?: string,
|
|
39
|
+
): Promise<ReleaseCreationResult> => {
|
|
40
|
+
// 1. Create Jira version (mandatory)
|
|
41
|
+
const versionName = `v${version}`
|
|
42
|
+
|
|
43
|
+
const result = await createJiraVersion(
|
|
44
|
+
{
|
|
45
|
+
name: versionName,
|
|
46
|
+
projectId: jiraConfig.projectId,
|
|
47
|
+
description: description || '',
|
|
48
|
+
released: false,
|
|
49
|
+
archived: false,
|
|
50
|
+
},
|
|
51
|
+
jiraConfig,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
// Construct user-friendly Jira URL using project key from API response
|
|
55
|
+
const jiraVersionUrl = `${jiraConfig.baseUrl}/projects/${result.version!.projectId}/versions/${result.version!.id}/tab/release-report-all-issues`
|
|
56
|
+
|
|
57
|
+
// 2. Create GitHub release branch
|
|
58
|
+
const releaseInfo = await createReleaseBranch({ version, jiraVersionUrl })
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
version,
|
|
62
|
+
branchName: releaseInfo.branchName,
|
|
63
|
+
prUrl: releaseInfo.prUrl,
|
|
64
|
+
jiraVersionUrl,
|
|
65
|
+
}
|
|
66
|
+
}
|
package/src/mcp/tools/index.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
2
2
|
|
|
3
3
|
import { ghMergeDevMcpTool } from 'src/commands/gh-merge-dev'
|
|
4
|
-
import { ghReleaseCreateMcpTool } from 'src/commands/gh-release-create'
|
|
5
4
|
import { ghReleaseDeliverMcpTool } from 'src/commands/gh-release-deliver'
|
|
6
5
|
import { ghReleaseDeployMcpTool } from 'src/commands/gh-release-deploy'
|
|
7
6
|
import { ghReleaseListMcpTool } from 'src/commands/gh-release-list'
|
|
7
|
+
import { releaseCreateMcpTool } from 'src/commands/release-create'
|
|
8
|
+
import { releaseCreateBatchMcpTool } from 'src/commands/release-create-batch'
|
|
8
9
|
import { worktreesAddMcpTool } from 'src/commands/worktrees-add'
|
|
9
10
|
import { worktreesListMcpTool } from 'src/commands/worktrees-list'
|
|
10
11
|
import { worktreesRemoveMcpTool } from 'src/commands/worktrees-remove'
|
|
@@ -13,7 +14,8 @@ import { createToolHandler } from 'src/lib/tool-handler'
|
|
|
13
14
|
|
|
14
15
|
const tools = [
|
|
15
16
|
ghMergeDevMcpTool,
|
|
16
|
-
|
|
17
|
+
releaseCreateMcpTool,
|
|
18
|
+
releaseCreateBatchMcpTool,
|
|
17
19
|
ghReleaseDeliverMcpTool,
|
|
18
20
|
ghReleaseDeployMcpTool,
|
|
19
21
|
ghReleaseListMcpTool,
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import confirm from '@inquirer/confirm'
|
|
2
|
-
import process from 'node:process'
|
|
3
|
-
import { z } from 'zod'
|
|
4
|
-
import { $, question } from 'zx'
|
|
5
|
-
|
|
6
|
-
import { createReleaseBranch } from 'src/integrations/gh'
|
|
7
|
-
import { createJiraVersion, loadJiraConfig } from 'src/integrations/jira'
|
|
8
|
-
import { logger } from 'src/lib/logger'
|
|
9
|
-
import type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'
|
|
10
|
-
|
|
11
|
-
interface GhReleaseCreateArgs extends RequiredConfirmedOptionArg {
|
|
12
|
-
versions: string
|
|
13
|
-
checkout?: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Create release branches for a given version
|
|
18
|
-
*/
|
|
19
|
-
export const ghReleaseCreate = async (args: GhReleaseCreateArgs): Promise<ToolsExecutionResult> => {
|
|
20
|
-
const { versions, confirmedCommand, checkout } = args
|
|
21
|
-
|
|
22
|
-
let versionBranches = ''
|
|
23
|
-
let _checkout = checkout
|
|
24
|
-
|
|
25
|
-
// Load Jira config - it is now mandatory
|
|
26
|
-
const jiraConfig = await loadJiraConfig()
|
|
27
|
-
|
|
28
|
-
if (versions) {
|
|
29
|
-
versionBranches = versions
|
|
30
|
-
} else {
|
|
31
|
-
versionBranches = await question('Enter versions by comma (e.g. 1.2.5, 1.2.6): ')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const versionsList = versionBranches.split(',').map((version) => version.trim()) // ['1.2.5', '1.2.6']
|
|
35
|
-
|
|
36
|
-
// Validate input
|
|
37
|
-
if (versionsList.length === 0) {
|
|
38
|
-
logger.error('No versions provided. Exiting...')
|
|
39
|
-
process.exit(1)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Warn user if checkout option is used with multiple branches
|
|
43
|
-
if (_checkout && versionsList.length > 1) {
|
|
44
|
-
logger.warn(
|
|
45
|
-
'⚠️ Checkout option is ignored when creating multiple branches. Only works with single branch creation.',
|
|
46
|
-
)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (versionsList.length === 1 && !_checkout) {
|
|
50
|
-
_checkout = await confirm({
|
|
51
|
-
message: `Checkout to the created branch?`,
|
|
52
|
-
})
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const answer = confirmedCommand
|
|
56
|
-
? true
|
|
57
|
-
: await confirm({
|
|
58
|
-
message: `Are you sure you want to create release branches for these versions: ${versionsList.join(', ')}?`,
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
if (!answer) {
|
|
62
|
-
logger.info('Operation cancelled. Exiting...')
|
|
63
|
-
process.exit(0)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
$.quiet = true
|
|
67
|
-
|
|
68
|
-
await $`git fetch origin`
|
|
69
|
-
await $`git switch dev`
|
|
70
|
-
await $`git pull origin dev`
|
|
71
|
-
|
|
72
|
-
const releases: Array<{
|
|
73
|
-
version: string
|
|
74
|
-
branchName: string
|
|
75
|
-
prUrl: string
|
|
76
|
-
jiraVersionUrl: string
|
|
77
|
-
}> = []
|
|
78
|
-
|
|
79
|
-
for (const version of versionsList) {
|
|
80
|
-
// 1. Create Jira version (mandatory)
|
|
81
|
-
const versionName = `v${version}`
|
|
82
|
-
|
|
83
|
-
const result = await createJiraVersion(
|
|
84
|
-
{
|
|
85
|
-
name: versionName,
|
|
86
|
-
projectId: jiraConfig.projectId,
|
|
87
|
-
description: ``,
|
|
88
|
-
released: false,
|
|
89
|
-
archived: false,
|
|
90
|
-
},
|
|
91
|
-
jiraConfig,
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
// 2. Create GitHub release branch
|
|
95
|
-
const releaseInfo = await createReleaseBranch(version)
|
|
96
|
-
|
|
97
|
-
// Construct user-friendly Jira URL using project key from API response
|
|
98
|
-
const jiraVersionUrl = `${jiraConfig.baseUrl}/projects/${result.version!.projectId}/versions/${result.version!.id}/tab/release-report-all-issues`
|
|
99
|
-
|
|
100
|
-
releases.push({
|
|
101
|
-
version,
|
|
102
|
-
branchName: releaseInfo.branchName,
|
|
103
|
-
prUrl: releaseInfo.prUrl,
|
|
104
|
-
jiraVersionUrl,
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
logger.info(`✅ Successfully created release: ${versionName}`)
|
|
108
|
-
logger.info(`🔗 GitHub PR: ${releaseInfo.prUrl}`)
|
|
109
|
-
logger.info(`🔗 Jira Version: ${jiraVersionUrl} \n`)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// If checkout option is enabled and we created only one branch, checkout to it
|
|
113
|
-
const isCheckedOut = _checkout && versionsList.length === 1
|
|
114
|
-
|
|
115
|
-
if (isCheckedOut) {
|
|
116
|
-
const branchName = `release/v${versionsList[0]}`
|
|
117
|
-
|
|
118
|
-
await $`git switch ${branchName}`
|
|
119
|
-
|
|
120
|
-
logger.info(`🔄 Switched to branch ${branchName}`)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
logger.info(`${versionsList.length} release branches were created successfully.`)
|
|
124
|
-
|
|
125
|
-
$.quiet = false
|
|
126
|
-
|
|
127
|
-
const structuredContent = {
|
|
128
|
-
createdBranches: versionsList.map((version) => `release/v${version}`),
|
|
129
|
-
branchCount: versionsList.length,
|
|
130
|
-
isCheckedOut,
|
|
131
|
-
releases,
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
content: [
|
|
136
|
-
{
|
|
137
|
-
type: 'text',
|
|
138
|
-
text: JSON.stringify(structuredContent, null, 2),
|
|
139
|
-
},
|
|
140
|
-
],
|
|
141
|
-
structuredContent,
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// MCP Tool Registration
|
|
146
|
-
export const ghReleaseCreateMcpTool = {
|
|
147
|
-
name: 'gh-release-create',
|
|
148
|
-
description: 'Create new release branches for specified versions and optionally create Jira versions',
|
|
149
|
-
inputSchema: {
|
|
150
|
-
versions: z.string().describe('Comma-separated list of versions to create (e.g., "1.2.5, 1.2.6")'),
|
|
151
|
-
checkout: z.boolean().optional().describe('Checkout to the created branch (only works with single version)'),
|
|
152
|
-
},
|
|
153
|
-
outputSchema: {
|
|
154
|
-
createdBranches: z.array(z.string()).describe('List of created release branches'),
|
|
155
|
-
branchCount: z.number().describe('Number of branches created'),
|
|
156
|
-
isCheckedOut: z.boolean().describe('Whether the branch was checked out'),
|
|
157
|
-
releases: z
|
|
158
|
-
.array(
|
|
159
|
-
z.object({
|
|
160
|
-
version: z.string().describe('Version number'),
|
|
161
|
-
branchName: z.string().describe('Release branch name'),
|
|
162
|
-
prUrl: z.string().describe('GitHub PR URL'),
|
|
163
|
-
jiraVersionUrl: z.string().describe('Jira version URL'),
|
|
164
|
-
}),
|
|
165
|
-
)
|
|
166
|
-
.describe('Detailed information for each created release with URLs only'),
|
|
167
|
-
},
|
|
168
|
-
handler: ghReleaseCreate,
|
|
169
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ghReleaseCreate, ghReleaseCreateMcpTool } from './gh-release-create'
|
|
File without changes
|