@@ -10,30 +10,35 @@ import type { BuilderPlugin } from './types.js'
1010const RUN_SHARED_ASSETS_DIR = 'assetsGitDir'
1111
1212export interface GitHubRepoSyncPluginOptions {
13+ repo : {
14+ enable : boolean
15+ url : string
16+ token ?: string
17+ branch ?: string
18+ }
1319 autoPush ?: boolean
1420}
1521
16- export default function githubRepoSyncPlugin ( options : GitHubRepoSyncPluginOptions = { } ) : BuilderPlugin {
22+ export default function githubRepoSyncPlugin ( options : GitHubRepoSyncPluginOptions ) : BuilderPlugin {
1723 const autoPush = options . autoPush ?? true
24+ const repoConfig = options . repo
25+
26+ if ( ! repoConfig ) {
27+ throw new Error ( 'githubRepoSyncPlugin 需要 repo 配置' )
28+ }
29+
30+ const branchName = repoConfig . branch ?. trim ( ) || 'main'
1831
1932 return {
2033 name : 'afilmory:github-repo-sync' ,
2134 hooks : {
2235 beforeBuild : async ( context ) => {
23- const userConfig = context . config . user
24- if ( ! userConfig ) {
25- context . logger . main . warn ( '⚠️ 未配置用户级设置,跳过远程仓库同步' )
26- return
27- }
28-
29- if ( ! userConfig . repo . enable ) {
36+ if ( ! repoConfig . enable ) {
3037 return
3138 }
3239
3340 const { logger } = context
34- const { repo } = userConfig
35-
36- if ( ! repo . url ) {
41+ if ( ! repoConfig . url ) {
3742 logger . main . warn ( '⚠️ 未配置远程仓库地址,跳过同步' )
3843 return
3944 }
@@ -43,7 +48,7 @@ export default function githubRepoSyncPlugin(options: GitHubRepoSyncPluginOption
4348
4449 logger . main . info ( '🔄 同步远程仓库...' )
4550
46- const repoUrl = buildAuthenticatedRepoUrl ( repo . url , repo . token )
51+ const repoUrl = buildAuthenticatedRepoUrl ( repoConfig . url , repoConfig . token )
4752
4853 if ( ! existsSync ( assetsGitDir ) ) {
4954 logger . main . info ( '📥 克隆远程仓库...' )
@@ -67,17 +72,12 @@ export default function githubRepoSyncPlugin(options: GitHubRepoSyncPluginOption
6772 }
6873 }
6974
75+ await ensureRepositoryBranch ( { assetsGitDir, branchName, logger } )
7076 await prepareRepositoryLayout ( { assetsGitDir, logger } )
7177 logger . main . success ( '✅ 远程仓库同步完成' )
7278 } ,
7379 afterBuild : async ( context ) => {
74- const userConfig = context . config . user
75- if ( ! userConfig ) {
76- context . logger . main . warn ( '⚠️ 未配置用户级设置,跳过推送' )
77- return
78- }
79-
80- if ( ! autoPush || ! userConfig . repo . enable ) {
80+ if ( ! autoPush || ! repoConfig . enable ) {
8181 return
8282 }
8383
@@ -97,7 +97,8 @@ export default function githubRepoSyncPlugin(options: GitHubRepoSyncPluginOption
9797 await pushUpdatesToRemoteRepo ( {
9898 assetsGitDir,
9999 logger : context . logger ,
100- repoConfig : userConfig . repo ,
100+ repoConfig,
101+ branchName,
101102 } )
102103 } ,
103104 } ,
@@ -152,9 +153,15 @@ interface PushRemoteOptions {
152153 url : string
153154 token ?: string
154155 }
156+ branchName : string
155157}
156158
157- async function pushUpdatesToRemoteRepo ( { assetsGitDir, logger, repoConfig } : PushRemoteOptions ) : Promise < void > {
159+ async function pushUpdatesToRemoteRepo ( {
160+ assetsGitDir,
161+ logger,
162+ repoConfig,
163+ branchName,
164+ } : PushRemoteOptions ) : Promise < void > {
158165 if ( ! repoConfig . url ) {
159166 return
160167 }
@@ -194,7 +201,7 @@ async function pushUpdatesToRemoteRepo({ assetsGitDir, logger, repoConfig }: Pus
194201 cwd : assetsGitDir ,
195202 stdio : 'inherit' ,
196203 } ) `git commit -m ${ commitMessage } `
197- await $ ( { cwd : assetsGitDir , stdio : 'inherit' } ) `git push origin HEAD`
204+ await $ ( { cwd : assetsGitDir , stdio : 'inherit' } ) `git push -u origin HEAD: ${ branchName } `
198205
199206 logger . main . success ( '✅ 成功推送更新到远程仓库' )
200207}
@@ -214,6 +221,71 @@ async function ensureGitUserConfigured(assetsGitDir: string): Promise<void> {
214221 }
215222}
216223
224+ interface EnsureRepositoryBranchOptions {
225+ assetsGitDir : string
226+ branchName : string
227+ logger : typeof import ( '../logger/index.js' ) . logger
228+ }
229+
230+ async function ensureRepositoryBranch ( {
231+ assetsGitDir,
232+ branchName,
233+ logger,
234+ } : EnsureRepositoryBranchOptions ) : Promise < void > {
235+ const currentBranch = await getCurrentBranch ( assetsGitDir )
236+
237+ if ( currentBranch === branchName ) {
238+ return
239+ }
240+
241+ const hasLocalBranch = await branchExistsLocally ( assetsGitDir , branchName )
242+ if ( hasLocalBranch ) {
243+ logger . main . info ( `🔀 切换到分支 ${ branchName } ` )
244+ await $ ( { cwd : assetsGitDir , stdio : 'inherit' } ) `git checkout ${ branchName } `
245+ return
246+ }
247+
248+ if ( await remoteBranchExists ( assetsGitDir , branchName ) ) {
249+ logger . main . info ( `🔄 检出远程分支 ${ branchName } ` )
250+ await $ ( { cwd : assetsGitDir , stdio : 'inherit' } ) `git checkout -b ${ branchName } origin/${ branchName } `
251+ return
252+ }
253+
254+ logger . main . info ( `🌱 创建新分支 ${ branchName } ` )
255+ await $ ( { cwd : assetsGitDir , stdio : 'inherit' } ) `git checkout -b ${ branchName } `
256+ }
257+
258+ async function getCurrentBranch ( assetsGitDir : string ) : Promise < string | null > {
259+ try {
260+ const { stdout } = await $ ( { cwd : assetsGitDir , stdio : 'pipe' } ) `git rev-parse --abbrev-ref HEAD`
261+ const branch = stdout . trim ( )
262+ if ( ! branch || branch === 'HEAD' ) {
263+ return null
264+ }
265+ return branch
266+ } catch {
267+ return null
268+ }
269+ }
270+
271+ async function branchExistsLocally ( assetsGitDir : string , branchName : string ) : Promise < boolean > {
272+ try {
273+ await $ ( { cwd : assetsGitDir , stdio : 'pipe' } ) `git show-ref --verify --quiet refs/heads/${ branchName } `
274+ return true
275+ } catch {
276+ return false
277+ }
278+ }
279+
280+ async function remoteBranchExists ( assetsGitDir : string , branchName : string ) : Promise < boolean > {
281+ try {
282+ await $ ( { cwd : assetsGitDir , stdio : 'pipe' } ) `git rev-parse --verify origin/${ branchName } `
283+ return true
284+ } catch {
285+ return false
286+ }
287+ }
288+
217289function buildAuthenticatedRepoUrl ( url : string , token ?: string ) : string {
218290 if ( ! token ) return url
219291
@@ -226,6 +298,6 @@ function buildAuthenticatedRepoUrl(url: string, token?: string): string {
226298}
227299
228300export const plugin = githubRepoSyncPlugin
229- export function createGitHubRepoSyncPlugin ( options ? : GitHubRepoSyncPluginOptions ) : BuilderPlugin {
301+ export function createGitHubRepoSyncPlugin ( options : GitHubRepoSyncPluginOptions ) : BuilderPlugin {
230302 return githubRepoSyncPlugin ( options )
231303}
0 commit comments