88 * @fileoverview Git-related gulp tasks for Blockly.
99 */
1010
11+
1112import * as gulp from 'gulp' ;
1213import { execSync } from 'child_process' ;
14+ import yargs from 'yargs' ;
15+ import { hideBin } from 'yargs/helpers' ;
1316
1417import * as buildTasks from './build_tasks.mjs' ;
1518import * as packageTasks from './package_tasks.mjs' ;
1619
17- const UPSTREAM_URL = 'https://github.com/google/blockly.git' ;
20+ const UPSTREAM_URL = 'git@github.com:RaspberryPiFoundation/blockly.git' ;
21+
22+ // Use yargs to parse --remote argument
23+ const argv = yargs ( hideBin ( process . argv ) ) . option ( 'remote' , {
24+ type : 'string' ,
25+ describe : 'Remote to push gh-pages to' ,
26+ demandOption : false
27+ } ) . option ( 'upstream' , {
28+ type : 'boolean' ,
29+ describe : 'Push to RaspberryPiFoundation/blockly instead of origin' ,
30+ demandOption : false
31+ } ) . option ( 'use-local' , {
32+ type : 'boolean' ,
33+ describe : 'Build and push from current branch instead of syncing with main' ,
34+ demandOption : false
35+ } ) . help ( ) . argv ;
36+ const remoteToUse = argv . upstream ? UPSTREAM_URL : resolveRemote ( argv . remote ) ;
1837
1938/**
2039 * Extra paths to include in the gh_pages branch (beyond the normal
21- * contents of master / develop ). Passed to shell unquoted, so can
40+ * contents of main ). Passed to shell unquoted, so can
2241 * include globs.
2342 */
2443const EXTRAS = [
@@ -28,140 +47,122 @@ const EXTRAS = [
2847 'build/*.loader.mjs' ,
2948] ;
3049
31- let upstream = null ;
32-
3350/**
34- * Get name of git remote for upstream (typically 'upstream', but this
35- * is just convention and can be changed.)
36- */
37- function getUpstream ( ) {
38- if ( upstream ) return upstream ;
39- for ( const line of String ( execSync ( 'git remote -v' ) ) . split ( '\n' ) ) {
40- if ( line . includes ( 'google/blockly' ) ) {
41- upstream = line . split ( '\t' ) [ 0 ] ;
42- return upstream ;
43- }
44- }
45- throw new Error ( 'Unable to determine upstream URL' ) ;
46- }
47-
48- /**
49- * Stash current state, check out the named branch, and sync with
50- * google/blockly.
51+ * Stash current state, check out the named branch, and pull
52+ * changes from RaspberryPiFoundation/blockly.
5153 */
5254function syncBranch ( branchName ) {
5355 return function ( done ) {
5456 execSync ( 'git stash save -m "Stash for sync"' , { stdio : 'inherit' } ) ;
5557 checkoutBranch ( branchName ) ;
5658 execSync ( `git pull ${ UPSTREAM_URL } ${ branchName } ` , { stdio : 'inherit' } ) ;
57- execSync ( `git push origin ${ branchName } ` , { stdio : 'inherit' } ) ;
5859 done ( ) ;
5960 } ;
6061}
6162
6263/**
63- * Stash current state, check out develop , and sync with
64- * google /blockly.
64+ * Stash current state, check out main , and sync with
65+ * RaspberryPiFoundation /blockly.
6566 */
66- export function syncDevelop ( ) {
67- return syncBranch ( 'develop ' ) ;
67+ export function syncMain ( ) {
68+ return syncBranch ( 'main ' ) ;
6869} ;
6970
7071/**
71- * Stash current state, check out master, and sync with
72- * google/blockly.
73- */
74- export function syncMaster ( ) {
75- return syncBranch ( 'master' ) ;
76- } ;
77-
78- /**
79- * Helper function: get a name for a rebuild branch. Format:
80- * rebuild_mm_dd_yyyy.
81- */
82- function getRebuildBranchName ( ) {
83- const date = new Date ( ) ;
84- const mm = date . getMonth ( ) + 1 ; // Month, 0-11
85- const dd = date . getDate ( ) ; // Day of the month, 1-31
86- const yyyy = date . getFullYear ( ) ;
87- return `rebuild_${ mm } _${ dd } _${ yyyy } ` ;
88- } ;
89-
90- /**
91- * Helper function: get a name for a rebuild branch. Format:
92- * rebuild_yyyy_mm.
93- */
94- function getRCBranchName ( ) {
95- const date = new Date ( ) ;
96- const mm = date . getMonth ( ) + 1 ; // Month, 0-11
97- const yyyy = date . getFullYear ( ) ;
98- return `rc_${ yyyy } _${ mm } ` ;
99- } ;
100-
101- /**
102- * If branch does not exist then create the branch.
10372 * If branch exists switch to branch.
73+ * If branch does not exist then create the branch.
10474 */
10575function checkoutBranch ( branchName ) {
106- execSync ( `git switch -c ${ branchName } ` ,
76+ execSync ( `git switch ${ branchName } || git switch -c ${ branchName } ` ,
10777 { stdio : 'inherit' } ) ;
10878}
10979
11080/**
111- * Create and push an RC branch.
112- * Note that this pushes to google/blockly.
113- */
114- export const createRC = gulp . series (
115- syncDevelop ( ) ,
116- function ( done ) {
117- const branchName = getRCBranchName ( ) ;
118- execSync ( `git switch -C ${ branchName } ` , { stdio : 'inherit' } ) ;
119- execSync ( `git push ${ UPSTREAM_URL } ${ branchName } ` , { stdio : 'inherit' } ) ;
120- done ( ) ;
121- }
122- ) ;
123-
124- /** Create the rebuild branch. */
125- export function createRebuildBranch ( done ) {
126- const branchName = getRebuildBranchName ( ) ;
127- console . log ( `make-rebuild-branch: creating branch ${ branchName } ` ) ;
128- execSync ( `git switch -C ${ branchName } ` , { stdio : 'inherit' } ) ;
129- done ( ) ;
130- }
131-
132- /** Push the rebuild branch to origin. */
133- export function pushRebuildBranch ( done ) {
134- console . log ( 'push-rebuild-branch: committing rebuild' ) ;
135- execSync ( 'git commit -am "Rebuild"' , { stdio : 'inherit' } ) ;
136- const branchName = getRebuildBranchName ( ) ;
137- execSync ( `git push origin ${ branchName } ` , { stdio : 'inherit' } ) ;
138- console . log ( `Branch ${ branchName } pushed to GitHub.` ) ;
139- console . log ( 'Next step: create a pull request against develop.' ) ;
140- done ( ) ;
141- }
142-
143- /**
144- * Update github pages with what is currently in develop.
81+ * Update github pages with what is currently in main (or current branch if --use-local).
14582 *
14683 * Prerequisites (invoked): clean, build.
84+ *
85+ * Usage:
86+ * gulp updateGithubPages # sync main, then use origin if exists
87+ * gulp updateGithubPages --upstream # uses hardcoded upstream
88+ * gulp updateGithubPages --remote <remote> # uses named remote
89+ * gulp updateGithubPages --use-local # build from current branch, skip syncing main
90+ *
14791 */
14892export const updateGithubPages = gulp . series (
149- function ( done ) {
150- execSync ( 'git stash save -m "Stash for sync"' , { stdio : 'inherit' } ) ;
151- execSync ( 'git switch -C gh-pages' , { stdio : 'inherit' } ) ;
152- execSync ( `git fetch ${ getUpstream ( ) } ` , { stdio : 'inherit' } ) ;
153- execSync ( `git reset --hard ${ getUpstream ( ) } /develop` , { stdio : 'inherit' } ) ;
154- done ( ) ;
155- } ,
156- buildTasks . cleanBuildDir ,
157- packageTasks . cleanReleaseDir ,
158- buildTasks . build ,
159- function ( done ) {
160- // Extra paths (e.g. build/, dist/ etc.) are normally gitignored,
161- // so we have to force add.
162- execSync ( `git add -f ${ EXTRAS . join ( ' ' ) } ` , { stdio : 'inherit' } ) ;
163- execSync ( 'git commit -am "Rebuild"' , { stdio : 'inherit' } ) ;
164- execSync ( `git push ${ UPSTREAM_URL } gh-pages --force` , { stdio : 'inherit' } ) ;
165- done ( ) ;
93+ function ( done ) {
94+ if ( ! remoteToUse ) {
95+ const attemptedRemote = argv . remote || 'origin' ;
96+ const remoteLabel = argv . remote
97+ ? `Remote '${ attemptedRemote } '`
98+ : "Remote 'origin' (default)" ;
99+ const errMsg = `${ remoteLabel } not found in git remotes. ` +
100+ 'Please add that remote or use --upstream.\n' +
101+ 'Usage: gulp updateGithubPages [--remote <remote> | --upstream]' ;
102+ console . error ( errMsg ) ;
103+ done ( new Error ( errMsg ) ) ;
104+ return ;
105+ }
106+ done ( ) ;
107+ } ,
108+ function ( done ) {
109+ if ( ! argv . useLocal ) {
110+ done ( ) ;
111+ return ;
112+ }
113+ const status = execSync ( 'git status --porcelain' , { encoding : 'utf8' } ) ;
114+ if ( status . trim ( ) ) {
115+ const errMsg =
116+ 'You cannot push the local branch with uncommitted changes. ' +
117+ 'Please commit or stash your changes first.' ;
118+ console . error ( errMsg ) ;
119+ done ( new Error ( errMsg ) ) ;
120+ return ;
121+ }
122+ done ( ) ;
123+ } ,
124+ function ( done ) {
125+ if ( argv . useLocal ) {
126+ done ( ) ;
127+ return ;
128+ }
129+ syncMain ( ) ( done ) ;
130+ } ,
131+ function ( done ) {
132+ const sourceRef = argv . useLocal
133+ ? execSync ( 'git rev-parse HEAD' , { encoding : 'utf8' } ) . trim ( )
134+ : 'main' ;
135+ execSync ( 'git switch -C gh-pages' , { stdio : 'inherit' } ) ;
136+ execSync ( `git reset --hard ${ sourceRef } ` , { stdio : 'inherit' } ) ;
137+ done ( ) ;
138+ } ,
139+ buildTasks . cleanBuildDir ,
140+ packageTasks . cleanReleaseDir ,
141+ buildTasks . build ,
142+ function ( done ) {
143+ // Extra paths (e.g. build/, dist/ etc.) are normally gitignored,
144+ // so we have to force add.
145+ execSync ( `git add -f ${ EXTRAS . join ( ' ' ) } ` , { stdio : 'inherit' } ) ;
146+ execSync ( 'git commit -am "Rebuild"' , { stdio : 'inherit' } ) ;
147+ execSync ( `git push ${ remoteToUse } gh-pages --force` , { stdio : 'inherit' } ) ;
148+ done ( ) ;
149+ }
150+ ) ;
151+
152+ /**
153+ * Resolves which remote to use for pushing gh-pages.
154+ * @param {string } remoteArg
155+ * @returns {string|undefined } The remote name, or undefined if not found.
156+ */
157+ function resolveRemote ( remoteArg ) {
158+ const remoteName = remoteArg || 'origin' ;
159+ try {
160+ const remotes = execSync ( 'git remote' , { encoding : 'utf8' } ) . split ( / \r ? \n / ) . map ( r => r . trim ( ) ) . filter ( Boolean ) ;
161+ if ( remotes . includes ( remoteName ) ) {
162+ return remoteName ;
163+ }
164+ return undefined ;
165+ } catch ( e ) {
166+ return undefined ;
166167 }
167- ) ;
168+ }
0 commit comments