infra-kit 0.1.44 → 0.1.50
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 +13 -14
- package/dist/cli.js.map +4 -4
- package/dist/mcp.js +12 -13
- package/dist/mcp.js.map +4 -4
- package/eslint.config.js +1 -1
- package/package.json +12 -13
- package/scripts/build.js +0 -1
- package/src/commands/gh-merge-dev/gh-merge-dev.ts +4 -6
- package/src/commands/gh-release-create/gh-release-create.ts +7 -7
- package/src/commands/gh-release-deliver/gh-release-deliver.ts +9 -2
- package/src/commands/gh-release-deploy/gh-release-deploy.ts +5 -2
- package/src/commands/gh-release-list/gh-release-list.ts +3 -5
- package/src/entry/cli.ts +3 -1
- package/src/integrations/acli/acli-auth/acli-auth.ts +25 -0
- package/src/integrations/acli/acli-auth/index.ts +1 -0
- package/src/integrations/acli/index.ts +1 -0
- package/src/integrations/gh/index.ts +1 -0
- package/src/lib/gh-release-prs/gh-release-prs.ts +5 -3
- package/src/lib/version-utils/version-utils.ts +2 -1
- package/src/mcp/server.ts +0 -1
- package/tsconfig.json +1 -1
- package/vitest.config.ts +16 -0
- package/vitest.setup.ts +1 -0
- /package/src/{lib → integrations/gh}/gh-cli-auth/gh-cli-auth.ts +0 -0
- /package/src/{lib → integrations/gh}/gh-cli-auth/index.ts +0 -0
package/scripts/build.js
CHANGED
|
@@ -9,7 +9,6 @@ const __filename = fileURLToPath(import.meta.url)
|
|
|
9
9
|
const __dirname = dirname(__filename)
|
|
10
10
|
|
|
11
11
|
const OUT_DIR = resolve(__dirname, '../dist')
|
|
12
|
-
|
|
13
12
|
const ENTRY_DIR = resolve(__dirname, '../src/entry')
|
|
14
13
|
|
|
15
14
|
const entryPoints = fs.readdirSync(ENTRY_DIR).map((file) => resolve(ENTRY_DIR, file))
|
|
@@ -76,13 +76,11 @@ export const ghMergeDev = async (args: GhMergeDevArgs): Promise<ToolsExecutionRe
|
|
|
76
76
|
logger.info('📋 Manual merge script for failed branches:\n')
|
|
77
77
|
logger.info('```bash')
|
|
78
78
|
for (const branch of failedBranches) {
|
|
79
|
-
logger.info(`# Merge dev into ${branch}`)
|
|
79
|
+
logger.info(`# Phase #1: Merge dev into ${branch}`)
|
|
80
80
|
logger.info(`git switch ${branch} && git pull origin ${branch} && git merge origin/dev`)
|
|
81
|
-
logger.info(`# Resolve conflicts if any, then:`)
|
|
81
|
+
logger.info(`# Phase #2:Resolve conflicts if any, then:`)
|
|
82
82
|
logger.info(`git push origin ${branch} && git switch dev`)
|
|
83
|
-
logger.info('')
|
|
84
83
|
}
|
|
85
|
-
logger.info('```\n')
|
|
86
84
|
logger.info(
|
|
87
85
|
`✅ ${selectedReleaseBranches.length - failedBranches.length}/${selectedReleaseBranches.length} merges completed successfully.`,
|
|
88
86
|
)
|
|
@@ -120,11 +118,11 @@ const mergeDev = async (branch: string): Promise<boolean> => {
|
|
|
120
118
|
|
|
121
119
|
await $`git switch dev`
|
|
122
120
|
|
|
123
|
-
logger.info(
|
|
121
|
+
logger.info(`Successfully merged dev into ${branch}`)
|
|
124
122
|
|
|
125
123
|
return true
|
|
126
124
|
} catch (error: unknown) {
|
|
127
|
-
logger.error({ error, branch },
|
|
125
|
+
logger.error({ error, branch }, `Error merging dev into ${branch}`)
|
|
128
126
|
|
|
129
127
|
await $`git reset --merge HEAD~1`
|
|
130
128
|
|
|
@@ -58,6 +58,8 @@ export const ghReleaseCreate = async (args: GhReleaseCreateArgs): Promise<ToolsE
|
|
|
58
58
|
process.exit(0)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
$.quiet = true
|
|
62
|
+
|
|
61
63
|
await $`git fetch origin`
|
|
62
64
|
|
|
63
65
|
await $`git switch dev`
|
|
@@ -75,14 +77,14 @@ export const ghReleaseCreate = async (args: GhReleaseCreateArgs): Promise<ToolsE
|
|
|
75
77
|
if (isCheckedOut) {
|
|
76
78
|
const branchName = `release/v${versionsList[0]}`
|
|
77
79
|
|
|
78
|
-
logger.info(`🔄 Checking out to ${branchName}...`)
|
|
79
|
-
|
|
80
80
|
await $`git switch ${branchName}`
|
|
81
81
|
|
|
82
|
-
logger.info(
|
|
82
|
+
logger.info(`🔄 Switched to branch ${branchName}`)
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
logger.info(
|
|
85
|
+
logger.info(`${versionsList.length} release branches were created successfully.`)
|
|
86
|
+
|
|
87
|
+
$.quiet = false
|
|
86
88
|
|
|
87
89
|
const structuredContent = {
|
|
88
90
|
createdBranches: versionsList.map((version) => `release/v${version}`),
|
|
@@ -107,8 +109,6 @@ export const ghReleaseCreate = async (args: GhReleaseCreateArgs): Promise<ToolsE
|
|
|
107
109
|
async function createReleaseBranch(version: string) {
|
|
108
110
|
const branchName = `release/v${version}`
|
|
109
111
|
|
|
110
|
-
logger.info(`Creating release branch ${branchName}...`)
|
|
111
|
-
|
|
112
112
|
try {
|
|
113
113
|
await $`git switch dev`
|
|
114
114
|
await $`git pull origin dev`
|
|
@@ -122,7 +122,7 @@ async function createReleaseBranch(version: string) {
|
|
|
122
122
|
await $`gh pr create --title "Release v${version}" --body "Release v${version}" --base dev --head ${branchName}`
|
|
123
123
|
|
|
124
124
|
await $`git switch dev`
|
|
125
|
-
logger.info(
|
|
125
|
+
logger.info(`Successfully created release branch: ${branchName}`)
|
|
126
126
|
} catch (error: unknown) {
|
|
127
127
|
logger.error({ error, branchName }, `Error creating release branch ${branchName}`)
|
|
128
128
|
}
|
|
@@ -52,19 +52,26 @@ export const ghReleaseDeliver = async (args: GhReleaseDeliverArgs): Promise<Tool
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
try {
|
|
55
|
+
$.quiet = true
|
|
56
|
+
|
|
55
57
|
await $`gh pr merge ${selectedReleaseBranch} --squash --admin --delete-branch` // TODO: add --body (AI for generate message)
|
|
56
58
|
|
|
57
59
|
await $`gh pr create --base main --head dev --title "Release v${selectedReleaseBranch.replace('release/v', '')} (RC)" --body ""`
|
|
58
60
|
|
|
59
61
|
await $`gh pr merge dev --squash --admin`
|
|
60
62
|
|
|
63
|
+
$.quiet = false
|
|
64
|
+
|
|
61
65
|
await $`gh workflow run deploy-all.yml --ref main -f environment=prod`
|
|
62
66
|
|
|
67
|
+
$.quiet = true
|
|
68
|
+
|
|
63
69
|
// Merge main into dev
|
|
64
70
|
await $`git switch main && git pull && git switch dev && git pull && git merge main --no-edit && git push`
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
$.quiet = false
|
|
73
|
+
|
|
74
|
+
logger.info(`Successfully delivered ${selectedReleaseBranch} to production!`)
|
|
68
75
|
|
|
69
76
|
const structuredContent = {
|
|
70
77
|
releaseBranch: selectedReleaseBranch,
|
|
@@ -67,11 +67,14 @@ export const ghReleaseDeploy = async (args: GhReleaseDeployArgs): Promise<ToolsE
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
try {
|
|
70
|
+
$.quiet = true
|
|
71
|
+
|
|
70
72
|
await $`gh workflow run deploy-all.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv}`
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
$.quiet = false
|
|
75
|
+
|
|
73
76
|
logger.info(
|
|
74
|
-
|
|
77
|
+
`Successfully launched deploy-all workflow_dispatch for release branch: ${selectedReleaseBranch} and environment: ${selectedEnv}`,
|
|
75
78
|
)
|
|
76
79
|
|
|
77
80
|
const structuredContent = {
|
|
@@ -2,7 +2,6 @@ import { z } from 'zod'
|
|
|
2
2
|
|
|
3
3
|
import { getReleasePRs } from 'src/lib/gh-release-prs'
|
|
4
4
|
import { logger } from 'src/lib/logger'
|
|
5
|
-
import { sortVersions } from 'src/lib/version-utils'
|
|
6
5
|
import type { ToolsExecutionResult } from 'src/types'
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -12,14 +11,13 @@ export const ghReleaseList = async (): Promise<ToolsExecutionResult> => {
|
|
|
12
11
|
const releasePRs = await getReleasePRs()
|
|
13
12
|
|
|
14
13
|
const releasePRsList = releasePRs.map((pr) => pr.replace('release/', ''))
|
|
15
|
-
const sortedReleases = sortVersions(releasePRsList)
|
|
16
14
|
|
|
17
15
|
logger.info('All release branches: \n')
|
|
18
|
-
logger.info(
|
|
16
|
+
logger.info(`\n${releasePRsList.join('\n')}`)
|
|
19
17
|
|
|
20
18
|
const structuredContent = {
|
|
21
|
-
releases:
|
|
22
|
-
count:
|
|
19
|
+
releases: releasePRsList,
|
|
20
|
+
count: releasePRsList.length,
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
return {
|
package/src/entry/cli.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander'
|
|
2
2
|
|
|
3
|
+
// Commands
|
|
3
4
|
import { ghMergeDev } from 'src/commands/gh-merge-dev'
|
|
4
5
|
import { ghReleaseCreate } from 'src/commands/gh-release-create'
|
|
5
6
|
import { ghReleaseDeliver } from 'src/commands/gh-release-deliver'
|
|
@@ -9,7 +10,8 @@ import { worktreesAdd } from 'src/commands/worktrees-add'
|
|
|
9
10
|
import { worktreesList } from 'src/commands/worktrees-list'
|
|
10
11
|
import { worktreesRemove } from 'src/commands/worktrees-remove'
|
|
11
12
|
import { worktreesSync } from 'src/commands/worktrees-sync'
|
|
12
|
-
|
|
13
|
+
// Integrations
|
|
14
|
+
import { validateGitHubCliAndAuth } from 'src/integrations/gh'
|
|
13
15
|
|
|
14
16
|
const program = new Command()
|
|
15
17
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
import { $ } from 'zx'
|
|
3
|
+
|
|
4
|
+
import { logger } from 'src/lib/logger'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Validate Atlassian CLI installation and authentication status and throw an error if not valid
|
|
8
|
+
*/
|
|
9
|
+
export const validateAtlassianCliAndAuth = async () => {
|
|
10
|
+
try {
|
|
11
|
+
await $`acli --version`
|
|
12
|
+
} catch (error: unknown) {
|
|
13
|
+
logger.error({ error }, 'Error: Atlassian CLI (atlassian) is not installed.')
|
|
14
|
+
logger.error('Please install it from: https://developer.atlassian.com/cloud/acli/guides/install-macos/')
|
|
15
|
+
process.exit(1)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
await $`gh auth status`
|
|
20
|
+
} catch (error: unknown) {
|
|
21
|
+
logger.error({ error }, 'Error: GitHub CLI (gh) is not authenticated.')
|
|
22
|
+
logger.error('Please authenticate it from: https://cli.github.com/manual/gh_auth_login or type "gh auth login"')
|
|
23
|
+
process.exit(1)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { validateAtlassianCliAndAuth } from './acli-auth'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { validateAtlassianCliAndAuth } from './acli-auth'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { validateGitHubCliAndAuth } from './gh-cli-auth'
|
|
@@ -2,6 +2,7 @@ import process from 'node:process'
|
|
|
2
2
|
import { $ } from 'zx'
|
|
3
3
|
|
|
4
4
|
import { logger } from 'src/lib/logger'
|
|
5
|
+
import { sortVersions } from 'src/lib/version-utils'
|
|
5
6
|
|
|
6
7
|
interface ReleasePR {
|
|
7
8
|
headRefName: string
|
|
@@ -13,10 +14,10 @@ interface ReleasePR {
|
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Fetch open release PRs from GitHub with 'Release' in the title and base 'dev'.
|
|
16
|
-
* Returns an array of headRefName strings.
|
|
17
|
+
* Returns an array of headRefName strings sorted by semver in ascending order.
|
|
17
18
|
* Throws an error if fetching fails.
|
|
18
19
|
*
|
|
19
|
-
* @returns [release/v1.18.22, release/v1.18.23, release/v1.18.24]
|
|
20
|
+
* @returns [release/v1.18.22, release/v1.18.23, release/v1.18.24] (sorted by semver)
|
|
20
21
|
*/
|
|
21
22
|
export const getReleasePRs = async (): Promise<string[]> => {
|
|
22
23
|
try {
|
|
@@ -31,7 +32,8 @@ export const getReleasePRs = async (): Promise<string[]> => {
|
|
|
31
32
|
process.exit(1)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
const headRefNames = releasePRsArray.map((pr) => pr.headRefName)
|
|
36
|
+
return sortVersions(headRefNames)
|
|
35
37
|
} catch (error) {
|
|
36
38
|
logger.error({ error }, '❌ Error fetching release PRs')
|
|
37
39
|
process.exit(1)
|
|
@@ -7,9 +7,10 @@ export const parseVersion = (versionStr: string): [number, number, number] => {
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Sort version strings in ascending order
|
|
10
|
+
* Note: Returns a new sorted array without mutating the original
|
|
10
11
|
*/
|
|
11
12
|
export const sortVersions = (versions: string[]): string[] => {
|
|
12
|
-
return versions.sort((a, b) => {
|
|
13
|
+
return [...versions].sort((a, b) => {
|
|
13
14
|
const [majA, minA, patchA] = parseVersion(a)
|
|
14
15
|
const [majB, minB, patchB] = parseVersion(b)
|
|
15
16
|
|
package/src/mcp/server.ts
CHANGED
package/tsconfig.json
CHANGED
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import react from '@vitejs/plugin-react-swc'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { defineConfig } from 'vitest/config'
|
|
4
|
+
|
|
5
|
+
export default defineConfig(() => ({
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
resolve: {
|
|
8
|
+
alias: {
|
|
9
|
+
'#root': path.resolve(__dirname, './src'),
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
test: {
|
|
13
|
+
environment: 'jsdom',
|
|
14
|
+
setupFiles: ['./vitest.setup.ts'],
|
|
15
|
+
},
|
|
16
|
+
}))
|
package/vitest.setup.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest'
|
|
File without changes
|
|
File without changes
|