diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5ab21a1bd..0e36ff9741 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node_version: [14.x, 16.x, 18.x] + node_version: [14, 16, 18] os: [ubuntu-latest, windows-latest] fail-fast: false steps: diff --git a/.github/workflows/pkg.pr.new.yml b/.github/workflows/pkg.pr.new.yml new file mode 100644 index 0000000000..13ed015b07 --- /dev/null +++ b/.github/workflows/pkg.pr.new.yml @@ -0,0 +1,79 @@ +name: Continuous Releases + +on: + push: + branches: + - master + - feature/* + pull_request: + types: + - opened + - synchronize + +jobs: + on-success: + env: + USE_NODE_VERSION: 18 + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Use Node.js ${{ env.USE_NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.USE_NODE_VERSION }} + registry-url: "https://registry.npmjs.org/" + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + target: wasm32-wasi + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + run_install: false + + # ========== Cache setup starts here ========== + # copied from .github/workflows/ci.yml + - name: Get pnpm store directory + id: pnpm-cache + run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} + key: ${{ runner.os }}-pnpm-store-node${{ env.USE_NODE_VERSION }}-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store-node${{ env.USE_NODE_VERSION }}- + + - name: Setup cargo cache + uses: actions/cache@v3 + with: + # ref: https://doc.rust-lang.org/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci + path: | + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-store-node${{ env.USE_NODE_VERSION }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-store-node${{ env.USE_NODE_VERSION }}- + # ========== Cache setup ends here ========== + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm build + + - name: Prepare examples + run: npx esno scripts/prepare-examples.ts + + - name: pkg-pr-new Publish + run: npx esno scripts/pkg-pr-new.ts diff --git a/.gitignore b/.gitignore index bfb98259ec..819a621005 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,7 @@ .dumi/tmp .dumi/tmp-production /examples/*/dist -/examples/*/.dumi/tmp -/examples/*/.dumi/tmp-production +/examples/*/.dumi/tmp* /docs/.upstream .idea /target diff --git a/examples/mobile/package.json b/examples/mobile/package.json index d56484515d..2c6747834d 100644 --- a/examples/mobile/package.json +++ b/examples/mobile/package.json @@ -1,5 +1,6 @@ { "name": "@examples/mobile", + "private": true, "scripts": { "build": "node ../../bin/dumi.js build", "dev": "node ../../bin/dumi.js dev", diff --git a/examples/normal/package.json b/examples/normal/package.json index 162c399a27..b4cb1d5fba 100644 --- a/examples/normal/package.json +++ b/examples/normal/package.json @@ -1,5 +1,6 @@ { "name": "@examples/normal", + "private": true, "scripts": { "build": "node ../../bin/dumi.js build", "dev": "node ../../bin/dumi.js dev", diff --git a/examples/vue/package.json b/examples/vue/package.json index 2cadb0f9a5..4dba192711 100644 --- a/examples/vue/package.json +++ b/examples/vue/package.json @@ -1,5 +1,6 @@ { "name": "@examples/vue", + "private": true, "description": "A Vue3 component library", "repository": { "type": "git", diff --git a/scripts/miscUtil.ts b/scripts/miscUtil.ts new file mode 100644 index 0000000000..a34f10ae25 --- /dev/null +++ b/scripts/miscUtil.ts @@ -0,0 +1,43 @@ +import { execa } from '@umijs/utils'; +import path from 'path'; + +interface IPackage { + name: string; + version: string; + private: boolean; + path: string; + dependencies?: Record; + devDependencies?: Record; + [key: string]: any; +} + +export const workspaces: IPackage[] = (function () { + try { + const { stdout } = execa.execaSync( + 'pnpm', + ['recursive', 'list', '--json'], + { + cwd: path.join(__dirname, '..'), + }, + ); + return JSON.parse(stdout); + } catch (error) { + return []; + } +})(); + +export const getExamples = () => { + const __examplesPath = path.join(__dirname, '../examples'); + return workspaces.filter((pkg) => { + return (pkg?.path || '').startsWith(__examplesPath); + }); +}; + +export function getPublishPackages() { + return workspaces.filter((pkg) => { + return [ + !pkg.private, // ignore private packages + !['create-dumi'].includes(pkg.name), // ignore by name + ].every(Boolean); + }); +} diff --git a/scripts/pkg-pr-new.ts b/scripts/pkg-pr-new.ts new file mode 100644 index 0000000000..56cfa7fd77 --- /dev/null +++ b/scripts/pkg-pr-new.ts @@ -0,0 +1,29 @@ +import { execa } from '@umijs/utils'; +import path from 'path'; +import { getExamples, getPublishPackages } from './miscUtil'; + +const rootPath = path.join(__dirname, '..'); + +function main() { + // https://github.com/stackblitz-labs/pkg.pr.new + const params = [ + // packages + ...getPublishPackages().map((pkg) => pkg.path), + // template + ...getExamples().map((example) => `--template=${example.path}`), + // more options + '--pnpm', + ]; + + console.log('🚀 pkg-pr-new', params); + + execa.execaSync('npx', ['pkg-pr-new', 'publish', ...params], { + stdio: 'inherit', + cwd: rootPath, + }); +} + +// \\\\\\\\\\\ +// \\\ main \\ +// \\\\\\\\\\\ +main(); diff --git a/scripts/prepare-examples.ts b/scripts/prepare-examples.ts new file mode 100644 index 0000000000..aaf190b9d7 --- /dev/null +++ b/scripts/prepare-examples.ts @@ -0,0 +1,53 @@ +import { fsExtra } from '@umijs/utils'; +import path from 'path'; +import { getExamples } from './miscUtil'; + +const rootPath = path.join(__dirname, '..'); + +function modifyPackageJson(pkgJson: any) { + return Object.assign({}, pkgJson, { + version: '0.0.1', // reset version + scripts: { + // ...pkgJson.scripts, // ignore original scripts + dev: 'dumi dev', + start: 'npm run dev', + build: 'dumi build', + preview: 'dumi preview', + setup: 'dumi setup', + }, + dependencies: { + ...pkgJson.dependencies, + dumi: 'workspace:*', + }, + }); +} + +function main() { + for (const example of getExamples()) { + const pkgJson = fsExtra.readJSONSync( + path.join(example.path, 'package.json'), + ); + const newPkgJson = modifyPackageJson(pkgJson); + + const rewritePath = process.env.CI + ? example.path + : path.join(example.path, '.dumi/tmp_prepare' /** ignored */); + + const pkgFile = path.join(rewritePath, 'package.json'); + + fsExtra.ensureFileSync(pkgFile); + fsExtra.writeJSONSync(pkgFile, newPkgJson, { spaces: 2 }); + + console.log( + `[${example.name}] Successfully prepared package.json => ${path.relative( + rootPath, + pkgFile, + )}`, + ); + } +} + +// \\\\\\\\\\\ +// \\\ main \\ +// \\\\\\\\\\\ +main();