Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ jobs:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Initialize CodeQL
uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # 4.37.7
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # 4.37.8
with:
languages: javascript-typescript
config-file: ./.github/codeql/codeql-config.yml

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # 4.37.7
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # 4.37.8
72 changes: 52 additions & 20 deletions admin/scripts/generateExamples.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// @ts-check

import fs from 'fs-extra';
import shell from 'shelljs';
import {execa} from 'execa';

/**
* Generate one example per init template
Expand All @@ -23,17 +23,28 @@ async function generateTemplateExample(template) {
);

// Run the docusaurus script to create the template in the examples folder
const command = template.endsWith('-typescript')
? template.replace('-typescript', ' -- --typescript')
: `${template} -- --javascript`;

shell.exec(
const isTypeScript = template.endsWith('-typescript');
const templateName = isTypeScript
? template.replace('-typescript', '')
: template;
const templateFlag = isTypeScript ? '--typescript' : '--javascript';

await execa(
'yarn',
// We use the published init script on purpose, because the local init is
// too new and could generate upcoming/unavailable config options.
// Remember CodeSandbox templates will use the published version,
// not the repo version.
// Using "yarn create" because "npm init" still try to use local pkg
`yarn create docusaurus examples/${template} ${command}`,
[
'create',
'docusaurus',
`examples/${template}`,
templateName,
'--',
templateFlag,
],
{stdio: 'inherit'},
);

const templatePackageJson =
Expand Down Expand Up @@ -103,24 +114,35 @@ async function generateTemplateExample(template) {
* See https://github.com/jamstack/jamstack.org/pull/609
* Button visible here: https://jamstack.org/generators/
*/
function updateStarters() {
async function updateStarters() {
/**
* @param {Object} param0
* @param {string} param0.subfolder
* @param {string} param0.remote
* @param {string} param0.remoteBranch
*/
function forcePushGitSubtree({subfolder, remote, remoteBranch}) {
async function forcePushGitSubtree({subfolder, remote, remoteBranch}) {
console.log('');
// See https://stackoverflow.com/questions/33172857/how-do-i-force-a-subtree-push-to-overwrite-remote-changes
const command = `git push ${remote} \`git subtree split --prefix ${subfolder}\`:${remoteBranch} --force`;
try {
console.log(`forcePushGitSubtree command: ${command}`);
shell.exec(command);
console.log(`forcePushGitSubtree: splitting subtree ${subfolder}`);
const {stdout: splitCommit} = await execa(
'git',
['subtree', 'split', '--prefix', subfolder],
{stderr: 'inherit'},
);
console.log(
`forcePushGitSubtree: pushing ${splitCommit} to ${remote} ${remoteBranch}`,
);
await execa(
'git',
['push', remote, `${splitCommit}:${remoteBranch}`, '--force'],
{stdio: 'inherit'},
);
console.log('forcePushGitSubtree success!');
} catch (err) {
console.error(
`Can't force push to git subtree with command '${command}'`,
`Can't force push to git subtree ${subfolder} on ${remote} ${remoteBranch}`,
);
console.error(`If it's a permission problem, ask @slorber`);
console.error(err);
Expand All @@ -131,7 +153,7 @@ function updateStarters() {
console.log('');

console.log('Updating https://github.com/facebook/docusaurus/tree/starter');
forcePushGitSubtree({
await forcePushGitSubtree({
subfolder: 'examples/classic',
remote: 'origin',
remoteBranch: 'starter',
Expand All @@ -142,7 +164,7 @@ function updateStarters() {

// TODO replace by starter repo in Docusaurus-community org (if we get it)
console.log('Updating https://github.com/slorber/docusaurus-starter');
forcePushGitSubtree({
await forcePushGitSubtree({
subfolder: 'examples/classic',
remote: 'git@github.com:slorber/docusaurus-starter.git',
remoteBranch: 'main',
Expand All @@ -151,13 +173,21 @@ function updateStarters() {
console.log('');
}

const branch = shell.exec('git rev-parse --abbrev-ref HEAD').stdout;
const {stdout: branch} = await execa('git', [
'rev-parse',
'--abbrev-ref',
'HEAD',
]);
if (branch === 'main') {
throw new Error(
"Please don't generate Docusaurus examples from the main branch!\nWe are going to commit during this process!",
);
}
if (shell.exec('git diff --exit-code').code !== 0) {
const gitDiffResult = await execa('git', ['diff', '--exit-code'], {
stdio: 'inherit',
reject: false,
});
if (gitDiffResult.exitCode !== 0) {
throw new Error(
'Please run the generate examples command with a clean Git state and no uncommitted local changes. git diff should display nothing!',
);
Expand Down Expand Up @@ -188,16 +218,18 @@ for (const template of templates) {
await generateTemplateExample(template);
}
console.log('Committing changes');
shell.exec('git add examples');
shell.exec("git commit -am 'update examples' --allow-empty");
await execa('git', ['add', 'examples'], {stdio: 'inherit'});
await execa('git', ['commit', '-am', 'update examples', '--allow-empty'], {
stdio: 'inherit',
});

// Update starters
console.log(`
-------
# Updating starter repos and branches ...
It can take some time... please wait until done...
`);
updateStarters();
await updateStarters();

console.log(`
-------
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
},
"devDependencies": {
"@ai-sdk/react": "^3.0.177",
"@crowdin/cli": "^4.14.2",
"@crowdin/cli": "^5.0.1",
"@docusaurus/eslint-plugin": "3.10.1",
"@docusaurus/plugin-content-blog": "3.10.1",
"@docusaurus/plugin-content-docs": "3.10.1",
Expand All @@ -89,7 +89,6 @@
"@types/prompts": "^2.4.4",
"@types/react": "^19.2.14",
"@types/semver": "^7.7.1",
"@types/shelljs": "^0.8.12",
"@vitejs/plugin-react": "^6.0.2",
"@vitest/eslint-plugin": "^1.6.17",
"cross-env": "^10.1.0",
Expand All @@ -103,6 +102,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-regexp": "^3.1.0",
"execa": "^10.0.0",
"globals": "^17.6.0",
"husky": "^9.1.7",
"image-size": "^2.0.2",
Expand Down
1 change: 0 additions & 1 deletion packages/create-docusaurus/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

// We use cross-spawn instead of spawn because of Windows compatibility issues.
// For example, "yarn" doesn't work on Windows, it requires "yarn.cmd"
// Tools like execa() use cross-spawn under the hood, and "resolve" the command
import crossSpawn from 'cross-spawn';
import supportsColor from 'supports-color';
import {
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@docusaurus/logger": "3.10.1",
"@docusaurus/types": "3.10.1",
"@docusaurus/utils-common": "3.10.1",
"execa": "^5.1.1",
"execa": "^10.0.0",
"file-loader": "^6.2.0",
"fs-extra": "^11.2.0",
"github-slugger": "^2.0.0",
Expand Down
25 changes: 9 additions & 16 deletions packages/docusaurus-utils/src/vcs/__tests__/gitUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {describe, expect, it} from 'vitest';
import fs from 'fs-extra';
import path from 'path';
import os from 'os';
import execa from 'execa';
import {execa, type Options, type Result} from 'execa';

import {
FileNotTrackedError,
Expand Down Expand Up @@ -38,22 +38,13 @@ class Git {
cwd: string;
args: string[];
cmd: string;
options?: execa.Options;
}): Promise<execa.ExecaReturnValue> {
const res = await execa(cmd, args, {
options?: Options;
}): Promise<Result> {
return execa(cmd, args, {
cwd,
silent: true,
shell: true,
...options,
});
if (res.exitCode !== 0) {
throw new Error(
`Git command failed with code ${res.exitCode}: ${cmd} ${args.join(
' ',
)}`,
);
}
return res;
}

static async initializeRepo(dir: string): Promise<Git> {
Expand Down Expand Up @@ -83,8 +74,8 @@ class Git {
async runOptimisticGitCommand(
cmd: string,
args?: string[],
options?: execa.Options,
): Promise<execa.ExecaReturnValue> {
options?: Options,
): Promise<Result> {
return Git.runOptimisticGitCommand({cwd: this.dir, cmd, args, options});
}

Expand Down Expand Up @@ -538,8 +529,10 @@ describe('submodules APIs', () => {
[Error: Couldn't find the git superproject root directory
Failure while running \`git rev-parse --show-superproject-working-tree\` from cwd="<HOME_DIR>"
The command executed throws an error: Command failed with exit code 128: git rev-parse --show-superproject-working-tree

fatal: not a git repository (or any of the parent directories): .git]
Cause: [Error: Command failed with exit code 128: git rev-parse --show-superproject-working-tree
Cause: [ExecaError: Command failed with exit code 128: git rev-parse --show-superproject-working-tree

fatal: not a git repository (or any of the parent directories): .git]
`);
});
Expand Down
Loading
Loading