mirror of
https://github.com/google/blockly.git
synced 2026-04-26 23:20:22 +02:00
chore: improve gh-pages publishing steps (#9604)
* fix: Fix gulpfiles related to publishing GitHub pages * chore: remove unused gulp tasks * feat: allow passing a remote to push gh-pages to * feat: add ability to skip syncing with main * feat: add gh workflow to publish ghpages * chore: update node version --------- Co-authored-by: Aaron Dodson <aaron.dodson@raspberrypi.org>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
# Manual workflow to update GitHub Pages from a chosen source branch.
|
||||
# The gulp updateGithubPages task builds the repo and force-pushes to gh-pages.
|
||||
|
||||
name: Update GitHub Pages
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
source_branch:
|
||||
description: 'Source branch to build and deploy to GitHub Pages'
|
||||
required: true
|
||||
type: string
|
||||
default: main
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
update-gh-pages:
|
||||
timeout-minutes: 15
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ inputs.source_branch }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 24.x
|
||||
|
||||
- name: Update GitHub Pages
|
||||
working-directory: ./packages/blockly
|
||||
run: npm run updateGithubPages:staging
|
||||
@@ -33,18 +33,9 @@ import {
|
||||
tsc,
|
||||
} from './scripts/gulpfiles/build_tasks.mjs';
|
||||
import {docs} from './scripts/gulpfiles/docs_tasks.mjs';
|
||||
import {
|
||||
createRC,
|
||||
syncDevelop,
|
||||
syncMaster,
|
||||
updateGithubPages,
|
||||
} from './scripts/gulpfiles/git_tasks.mjs';
|
||||
import {updateGithubPages} from './scripts/gulpfiles/git_tasks.mjs';
|
||||
import {cleanReleaseDir, pack} from './scripts/gulpfiles/package_tasks.mjs';
|
||||
import {
|
||||
publish,
|
||||
publishBeta,
|
||||
recompile,
|
||||
} from './scripts/gulpfiles/release_tasks.mjs';
|
||||
import {publish, publishBeta} from './scripts/gulpfiles/release_tasks.mjs';
|
||||
import {
|
||||
generators,
|
||||
interactiveMocha,
|
||||
@@ -72,7 +63,7 @@ export {
|
||||
prepareDemos,
|
||||
deployDemosBeta,
|
||||
deployDemos,
|
||||
updateGithubPages as gitUpdateGithubPages,
|
||||
updateGithubPages,
|
||||
}
|
||||
|
||||
// Manually-invokable targets that also invoke prerequisites where
|
||||
@@ -86,15 +77,5 @@ export {
|
||||
generators as testGenerators,
|
||||
interactiveMocha,
|
||||
buildAdvancedCompilationTest,
|
||||
createRC as gitCreateRC,
|
||||
docs,
|
||||
}
|
||||
|
||||
// Legacy targets, to be deleted.
|
||||
//
|
||||
// prettier-ignore
|
||||
export {
|
||||
recompile,
|
||||
syncDevelop as gitSyncDevelop,
|
||||
syncMaster as gitSyncMaster,
|
||||
}
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
"prepareDemos": "gulp prepareDemos",
|
||||
"publish": "npm ci && gulp publish",
|
||||
"publish:beta": "npm ci && gulp publishBeta",
|
||||
"recompile": "gulp recompile",
|
||||
"release": "gulp gitCreateRC",
|
||||
"start": "npm run build && concurrently -n tsc,server \"tsc --watch --preserveWatchOutput --outDir \"build/src\" --declarationDir \"build/declarations\"\" \"http-server ./ -s -o /tests/playground.html -c-1\"",
|
||||
"tsc": "gulp tsc",
|
||||
"test": "gulp test",
|
||||
@@ -47,7 +45,8 @@
|
||||
"test:generators": "gulp testGenerators",
|
||||
"test:mocha:interactive": "npm run build && concurrently -n tsc,server \"tsc --watch --preserveWatchOutput --outDir \"build/src\" --declarationDir \"build/declarations\"\" \"gulp interactiveMocha\"",
|
||||
"test:compile:advanced": "gulp buildAdvancedCompilationTest --debug",
|
||||
"updateGithubPages": "npm ci && gulp gitUpdateGithubPages"
|
||||
"updateGithubPages": "npm ci && gulp updateGithubPages --upstream",
|
||||
"updateGithubPages:staging": "npm ci && gulp updateGithubPages --use-local"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
|
||||
@@ -8,17 +8,36 @@
|
||||
* @fileoverview Git-related gulp tasks for Blockly.
|
||||
*/
|
||||
|
||||
|
||||
import * as gulp from 'gulp';
|
||||
import {execSync} from 'child_process';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
|
||||
import * as buildTasks from './build_tasks.mjs';
|
||||
import * as packageTasks from './package_tasks.mjs';
|
||||
|
||||
const UPSTREAM_URL = 'https://github.com/google/blockly.git';
|
||||
const UPSTREAM_URL = 'git@github.com:RaspberryPiFoundation/blockly.git';
|
||||
|
||||
// Use yargs to parse --remote argument
|
||||
const argv = yargs(hideBin(process.argv)).option('remote', {
|
||||
type: 'string',
|
||||
describe: 'Remote to push gh-pages to',
|
||||
demandOption: false
|
||||
}).option('upstream', {
|
||||
type: 'boolean',
|
||||
describe: 'Push to RaspberryPiFoundation/blockly instead of origin',
|
||||
demandOption: false
|
||||
}).option('use-local', {
|
||||
type: 'boolean',
|
||||
describe: 'Build and push from current branch instead of syncing with main',
|
||||
demandOption: false
|
||||
}).help().argv;
|
||||
const remoteToUse = argv.upstream ? UPSTREAM_URL : resolveRemote(argv.remote);
|
||||
|
||||
/**
|
||||
* Extra paths to include in the gh_pages branch (beyond the normal
|
||||
* contents of master / develop). Passed to shell unquoted, so can
|
||||
* contents of main). Passed to shell unquoted, so can
|
||||
* include globs.
|
||||
*/
|
||||
const EXTRAS = [
|
||||
@@ -28,140 +47,122 @@ const EXTRAS = [
|
||||
'build/*.loader.mjs',
|
||||
];
|
||||
|
||||
let upstream = null;
|
||||
|
||||
/**
|
||||
* Get name of git remote for upstream (typically 'upstream', but this
|
||||
* is just convention and can be changed.)
|
||||
*/
|
||||
function getUpstream() {
|
||||
if (upstream) return upstream;
|
||||
for (const line of String(execSync('git remote -v')).split('\n')) {
|
||||
if (line.includes('google/blockly')) {
|
||||
upstream = line.split('\t')[0];
|
||||
return upstream;
|
||||
}
|
||||
}
|
||||
throw new Error('Unable to determine upstream URL');
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash current state, check out the named branch, and sync with
|
||||
* google/blockly.
|
||||
* Stash current state, check out the named branch, and pull
|
||||
* changes from RaspberryPiFoundation/blockly.
|
||||
*/
|
||||
function syncBranch(branchName) {
|
||||
return function(done) {
|
||||
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
|
||||
checkoutBranch(branchName);
|
||||
execSync(`git pull ${UPSTREAM_URL} ${branchName}`, { stdio: 'inherit' });
|
||||
execSync(`git push origin ${branchName}`, { stdio: 'inherit' });
|
||||
done();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stash current state, check out develop, and sync with
|
||||
* google/blockly.
|
||||
* Stash current state, check out main, and sync with
|
||||
* RaspberryPiFoundation/blockly.
|
||||
*/
|
||||
export function syncDevelop() {
|
||||
return syncBranch('develop');
|
||||
export function syncMain() {
|
||||
return syncBranch('main');
|
||||
};
|
||||
|
||||
/**
|
||||
* Stash current state, check out master, and sync with
|
||||
* google/blockly.
|
||||
*/
|
||||
export function syncMaster() {
|
||||
return syncBranch('master');
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function: get a name for a rebuild branch. Format:
|
||||
* rebuild_mm_dd_yyyy.
|
||||
*/
|
||||
function getRebuildBranchName() {
|
||||
const date = new Date();
|
||||
const mm = date.getMonth() + 1; // Month, 0-11
|
||||
const dd = date.getDate(); // Day of the month, 1-31
|
||||
const yyyy = date.getFullYear();
|
||||
return `rebuild_${mm}_${dd}_${yyyy}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function: get a name for a rebuild branch. Format:
|
||||
* rebuild_yyyy_mm.
|
||||
*/
|
||||
function getRCBranchName() {
|
||||
const date = new Date();
|
||||
const mm = date.getMonth() + 1; // Month, 0-11
|
||||
const yyyy = date.getFullYear();
|
||||
return `rc_${yyyy}_${mm}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* If branch does not exist then create the branch.
|
||||
* If branch exists switch to branch.
|
||||
* If branch does not exist then create the branch.
|
||||
*/
|
||||
function checkoutBranch(branchName) {
|
||||
execSync(`git switch -c ${branchName}`,
|
||||
execSync(`git switch ${branchName} || git switch -c ${branchName}`,
|
||||
{ stdio: 'inherit' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and push an RC branch.
|
||||
* Note that this pushes to google/blockly.
|
||||
*/
|
||||
export const createRC = gulp.series(
|
||||
syncDevelop(),
|
||||
function(done) {
|
||||
const branchName = getRCBranchName();
|
||||
execSync(`git switch -C ${branchName}`, { stdio: 'inherit' });
|
||||
execSync(`git push ${UPSTREAM_URL} ${branchName}`, { stdio: 'inherit' });
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
/** Create the rebuild branch. */
|
||||
export function createRebuildBranch(done) {
|
||||
const branchName = getRebuildBranchName();
|
||||
console.log(`make-rebuild-branch: creating branch ${branchName}`);
|
||||
execSync(`git switch -C ${branchName}`, { stdio: 'inherit' });
|
||||
done();
|
||||
}
|
||||
|
||||
/** Push the rebuild branch to origin. */
|
||||
export function pushRebuildBranch(done) {
|
||||
console.log('push-rebuild-branch: committing rebuild');
|
||||
execSync('git commit -am "Rebuild"', { stdio: 'inherit' });
|
||||
const branchName = getRebuildBranchName();
|
||||
execSync(`git push origin ${branchName}`, { stdio: 'inherit' });
|
||||
console.log(`Branch ${branchName} pushed to GitHub.`);
|
||||
console.log('Next step: create a pull request against develop.');
|
||||
done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update github pages with what is currently in develop.
|
||||
* Update github pages with what is currently in main (or current branch if --use-local).
|
||||
*
|
||||
* Prerequisites (invoked): clean, build.
|
||||
*
|
||||
* Usage:
|
||||
* gulp updateGithubPages # sync main, then use origin if exists
|
||||
* gulp updateGithubPages --upstream # uses hardcoded upstream
|
||||
* gulp updateGithubPages --remote <remote> # uses named remote
|
||||
* gulp updateGithubPages --use-local # build from current branch, skip syncing main
|
||||
*
|
||||
*/
|
||||
export const updateGithubPages = gulp.series(
|
||||
function(done) {
|
||||
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
|
||||
execSync('git switch -C gh-pages', { stdio: 'inherit' });
|
||||
execSync(`git fetch ${getUpstream()}`, { stdio: 'inherit' });
|
||||
execSync(`git reset --hard ${getUpstream()}/develop`, { stdio: 'inherit' });
|
||||
done();
|
||||
},
|
||||
buildTasks.cleanBuildDir,
|
||||
packageTasks.cleanReleaseDir,
|
||||
buildTasks.build,
|
||||
function(done) {
|
||||
// Extra paths (e.g. build/, dist/ etc.) are normally gitignored,
|
||||
// so we have to force add.
|
||||
execSync(`git add -f ${EXTRAS.join(' ')}`, {stdio: 'inherit'});
|
||||
execSync('git commit -am "Rebuild"', {stdio: 'inherit'});
|
||||
execSync(`git push ${UPSTREAM_URL} gh-pages --force`, {stdio: 'inherit'});
|
||||
done();
|
||||
function (done) {
|
||||
if (!remoteToUse) {
|
||||
const attemptedRemote = argv.remote || 'origin';
|
||||
const remoteLabel = argv.remote
|
||||
? `Remote '${attemptedRemote}'`
|
||||
: "Remote 'origin' (default)";
|
||||
const errMsg = `${remoteLabel} not found in git remotes. ` +
|
||||
'Please add that remote or use --upstream.\n' +
|
||||
'Usage: gulp updateGithubPages [--remote <remote> | --upstream]';
|
||||
console.error(errMsg);
|
||||
done(new Error(errMsg));
|
||||
return;
|
||||
}
|
||||
done();
|
||||
},
|
||||
function (done) {
|
||||
if (!argv.useLocal) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
const status = execSync('git status --porcelain', { encoding: 'utf8' });
|
||||
if (status.trim()) {
|
||||
const errMsg =
|
||||
'You cannot push the local branch with uncommitted changes. ' +
|
||||
'Please commit or stash your changes first.';
|
||||
console.error(errMsg);
|
||||
done(new Error(errMsg));
|
||||
return;
|
||||
}
|
||||
done();
|
||||
},
|
||||
function (done) {
|
||||
if (argv.useLocal) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
syncMain()(done);
|
||||
},
|
||||
function(done) {
|
||||
const sourceRef = argv.useLocal
|
||||
? execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim()
|
||||
: 'main';
|
||||
execSync('git switch -C gh-pages', { stdio: 'inherit' });
|
||||
execSync(`git reset --hard ${sourceRef}`, { stdio: 'inherit' });
|
||||
done();
|
||||
},
|
||||
buildTasks.cleanBuildDir,
|
||||
packageTasks.cleanReleaseDir,
|
||||
buildTasks.build,
|
||||
function(done) {
|
||||
// Extra paths (e.g. build/, dist/ etc.) are normally gitignored,
|
||||
// so we have to force add.
|
||||
execSync(`git add -f ${EXTRAS.join(' ')}`, {stdio: 'inherit'});
|
||||
execSync('git commit -am "Rebuild"', {stdio: 'inherit'});
|
||||
execSync(`git push ${remoteToUse} gh-pages --force`, {stdio: 'inherit'});
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Resolves which remote to use for pushing gh-pages.
|
||||
* @param {string} remoteArg
|
||||
* @returns {string|undefined} The remote name, or undefined if not found.
|
||||
*/
|
||||
function resolveRemote(remoteArg) {
|
||||
const remoteName = remoteArg || 'origin';
|
||||
try {
|
||||
const remotes = execSync('git remote', {encoding: 'utf8'}).split(/\r?\n/).map(r => r.trim()).filter(Boolean);
|
||||
if (remotes.includes(remoteName)) {
|
||||
return remoteName;
|
||||
}
|
||||
return undefined;
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,55 +18,6 @@ import * as packageTasks from './package_tasks.mjs';
|
||||
import {getPackageJson} from './helper_tasks.mjs';
|
||||
import {RELEASE_DIR} from './config.mjs';
|
||||
|
||||
|
||||
// Gets the current major version.
|
||||
function getMajorVersion() {
|
||||
const { version } = getPackageJson();
|
||||
const re = new RegExp(/^(\d)./);
|
||||
const match = re.exec(version);
|
||||
if (!match[0]) {
|
||||
return null;
|
||||
}
|
||||
console.log(match[0]);
|
||||
return parseInt(match[0]);
|
||||
}
|
||||
|
||||
// Updates the version depending on user input.
|
||||
function updateVersion(done, updateType) {
|
||||
const majorVersion = getMajorVersion();
|
||||
if (!majorVersion) {
|
||||
done(new Error('Something went wrong when getting the major version number.'));
|
||||
} else if (!updateType) {
|
||||
// User selected to cancel.
|
||||
done(new Error('Cancelling process.'));
|
||||
}
|
||||
|
||||
switch (updateType.toLowerCase()) {
|
||||
case 'major':
|
||||
majorVersion++;
|
||||
execSync(`npm --no-git-tag-version version ${majorVersion}.$(date +'%Y%m%d').0`, {stdio: 'inherit'});
|
||||
done();
|
||||
break;
|
||||
case 'minor':
|
||||
execSync(`npm --no-git-tag-version version ${majorVersion}.$(date +'%Y%m%d').0`, {stdio: 'inherit'});
|
||||
done();
|
||||
break;
|
||||
case 'patch':
|
||||
execSync(`npm --no-git-tag-version version patch`, {stdio: 'inherit'});
|
||||
done();
|
||||
break;
|
||||
default:
|
||||
done(new Error('Unexpected update type was chosen.'))
|
||||
}
|
||||
}
|
||||
|
||||
// Prompt the user to figure out what kind of version update we should do.
|
||||
function updateVersionPrompt(done) {
|
||||
const releaseTypes = ['Major', 'Minor', 'Patch'];
|
||||
const index = readlineSync.keyInSelect(releaseTypes, 'Which version type?');
|
||||
updateVersion(done, releaseTypes[index]);
|
||||
}
|
||||
|
||||
// Checks with the user that they are on the correct git branch.
|
||||
function checkBranch(done) {
|
||||
const gitBranchName = execSync('git rev-parse --abbrev-ref HEAD').toString();
|
||||
@@ -162,13 +113,3 @@ export const publishBeta = gulp.series(
|
||||
checkReleaseDir,
|
||||
loginAndPublishBeta
|
||||
);
|
||||
|
||||
// Switch to a new branch, update the version number, build Blockly
|
||||
// and check in the resulting built files.
|
||||
export const recompile = gulp.series(
|
||||
gitTasks.syncDevelop(),
|
||||
gitTasks.createRebuildBranch,
|
||||
updateVersionPrompt,
|
||||
packageTasks.pack, // Does clean + build.
|
||||
gitTasks.pushRebuildBranch
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user