Skip to content

Commit 20ee48c

Browse files
committed
refactor: extract withSpinner as reusable utility function
1 parent f5e0c40 commit 20ee48c

1 file changed

Lines changed: 97 additions & 80 deletions

File tree

src/git.ts

Lines changed: 97 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,33 @@ import { formatToken, parseRepo } from './utils'
99
// https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-a-repository-public-key
1010
export async function getRepoPublicKey(repoPath: string, config: SyncOptions): Promise<PublicKey> {
1111
const octokit = createOctokit(config)
12-
13-
const spinner = Spinner({ text: c.blue(`Fetching public key for ${repoPath}`) }).start()
1412
const { owner, repo } = parseRepo(repoPath)
1513
const url = `GET /repos/${owner}/${repo}/actions/secrets/public-key`
1614

17-
let res: PublicKey = { key: '', key_id: '' }
18-
if (!config.dry) {
19-
const { status, data } = await octokit.request(
20-
url,
21-
{
22-
owner,
23-
repo,
24-
headers: {
25-
'X-GitHub-Api-Version': config.apiVersion,
15+
return withSpinner<PublicKey>(
16+
`Fetching public key for ${repoPath}`,
17+
`Public key fetched successfully for ${repoPath}`,
18+
`Failed to fetch public key for ${repoPath}`,
19+
`Fetch Public Key: ${c.yellow(url)}`,
20+
{ key: '', key_id: '' },
21+
config,
22+
async () => {
23+
const { status, data } = await octokit.request(
24+
url,
25+
{
26+
owner,
27+
repo,
28+
headers: {
29+
'X-GitHub-Api-Version': config.apiVersion,
30+
},
2631
},
27-
},
28-
)
29-
if (status !== 200) {
30-
spinner.error(c.red(`Failed to fetch public key for ${repoPath}: ${status}`))
31-
console.error(c.red(JSON.stringify(data, null, 2)))
32-
process.exit(1)
33-
}
34-
res = data
35-
}
36-
else {
37-
console.log()
38-
console.log(c.yellow(`Get a repository public key: ${repoPath}`))
39-
}
40-
41-
spinner.success(c.green(`Public key fetched successfully for ${repoPath}`))
42-
return res
32+
)
33+
if (status !== 200) {
34+
throw new Error(`HTTP ${status}: ${JSON.stringify(data)}`)
35+
}
36+
return data as PublicKey
37+
},
38+
)
4339
}
4440

4541
// https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#create-or-update-a-repository-secret
@@ -51,78 +47,99 @@ export async function createOrUpdateRepoSecret(
5147
config: SyncOptions,
5248
) {
5349
const octokit = createOctokit(config)
54-
5550
secretName = `${config.envPrefix}${secretName}`
56-
57-
const spinner = Spinner({ text: c.blue(`Create or update ${secretName} for ${repoPath}`) }).start()
5851
const { owner, repo } = parseRepo(repoPath)
5952
const url = `PUT /repos/${owner}/${repo}/actions/secrets/${secretName}`
6053

61-
let res
62-
let operation = 'create or update'
63-
64-
if (!config.dry) {
65-
const { status, data } = await octokit.request(
66-
url,
67-
{
68-
owner,
69-
repo,
70-
secret_name: secretName,
71-
encrypted_value: await encrypt(secretValue, publicKey),
72-
key_id: publicKey.key_id,
73-
headers: {
74-
'X-GitHub-Api-Version': config.apiVersion,
54+
return withSpinner(
55+
`Create or update ${secretName} for ${repoPath}`,
56+
`${secretName} created/updated successfully for ${repoPath}`,
57+
`Failed to create or update ${secretName} for ${repoPath}`,
58+
`Create or Update Secret: ${c.yellow(url)}`,
59+
undefined,
60+
config,
61+
async () => {
62+
const { status, data } = await octokit.request(
63+
url,
64+
{
65+
owner,
66+
repo,
67+
secret_name: secretName,
68+
encrypted_value: await encrypt(secretValue, publicKey),
69+
key_id: publicKey.key_id,
70+
headers: {
71+
'X-GitHub-Api-Version': config.apiVersion,
72+
},
7573
},
76-
},
77-
)
78-
79-
if (status !== 201 && status !== 204) {
80-
spinner.error(c.red(`Failed to create or update ${secretName} for ${repoPath}`))
81-
console.error(c.red(JSON.stringify(data, null, 2)))
82-
process.exit(1)
83-
}
74+
)
8475

85-
operation = status === 201 ? 'created' : 'updated'
86-
res = data
87-
}
88-
else {
89-
console.log()
90-
console.log(c.yellow(`Create or update ${secretName} for ${repoPath}`))
91-
}
76+
if (status !== 201 && status !== 204) {
77+
throw new Error(`HTTP ${status}: ${JSON.stringify(data)}`)
78+
}
9279

93-
spinner.success(c.green(`${secretName} ${operation} successfully for ${repoPath}`))
94-
return res
80+
return data
81+
},
82+
)
9583
}
9684

9785
// https://docs.github.com/rest/repos/repos#list-repositories-for-the-authenticated-user
98-
export async function getRepos(config: SyncOptions) {
86+
export async function getRepos(config: SyncOptions): Promise<Repo[]> {
9987
const octokit = createOctokit(config)
88+
const url = 'GET /user/repos'
89+
90+
return withSpinner<Repo[]>(
91+
'Fetching repositories',
92+
'Repositories fetched successfully',
93+
'Failed to fetch repositories',
94+
`Fetch Repositories: ${c.yellow(url)}`,
95+
[],
96+
config,
97+
async () => {
98+
const { status, data } = await octokit.request(url, {
99+
headers: {
100+
'X-GitHub-Api-Version': config.apiVersion,
101+
},
102+
})
103+
if (status !== 200) {
104+
throw new Error(`HTTP ${status}: ${JSON.stringify(data)}`)
105+
}
106+
return data as Repo[]
107+
},
108+
)
109+
}
100110

101-
const spinner = Spinner({ text: c.blue('Fetching repositories') }).start()
111+
function createOctokit(config: SyncOptions) {
112+
return new Octokit({ auth: formatToken(config.token) })
113+
}
102114

103-
let res: Repo[] = []
115+
async function withSpinner<T>(
116+
loadingText: string,
117+
successText: string,
118+
failedText: string,
119+
dryText: string,
120+
defaultValue: T,
121+
config: SyncOptions,
122+
request: () => Promise<T>,
123+
): Promise<T> {
124+
const spinner = Spinner({ text: c.blue(loadingText) }).start()
125+
126+
let result: T
104127
if (!config.dry) {
105-
const { status, data } = await octokit.request('GET /user/repos', {
106-
headers: {
107-
'X-GitHub-Api-Version': config.apiVersion,
108-
},
109-
})
110-
if (status !== 200) {
111-
spinner.error(c.red('Failed to fetch repositories'))
112-
console.error(c.red(JSON.stringify(data, null, 2)))
128+
try {
129+
result = await request()
130+
spinner.success(c.green(successText))
131+
}
132+
catch (error) {
133+
spinner.error(c.red(failedText))
134+
console.error(c.red(JSON.stringify(error, null, 2)))
113135
process.exit(1)
114136
}
115-
res = data
116137
}
117138
else {
118139
console.log()
119-
console.log(c.yellow('Fetching repositories'))
140+
console.log(c.yellow(dryText))
141+
result = defaultValue
120142
}
121143

122-
spinner.success(c.green('Repositories fetched successfully'))
123-
return res
124-
}
125-
126-
function createOctokit(config: SyncOptions) {
127-
return new Octokit({ auth: formatToken(config.token) })
144+
return result
128145
}

0 commit comments

Comments
 (0)