diff --git a/.azure-pipelines/pipeline.yml b/.azure-pipelines/pipeline.yml index 0dc245e4..afdbed19 100644 --- a/.azure-pipelines/pipeline.yml +++ b/.azure-pipelines/pipeline.yml @@ -4,6 +4,7 @@ ############################################################################################### name: $(Date:yyyyMMdd)$(Rev:.r) +trigger: none pr: none resources: @@ -13,11 +14,6 @@ resources: name: microsoft/vscode-engineering ref: main endpoint: Monaco - - repository: vscode - type: github - name: microsoft/vscode - ref: main - endpoint: Monaco parameters: - name: quality @@ -27,29 +23,43 @@ parameters: values: - latest - next + - name: publishMonacoEditorCore + displayName: 🚀 Publish Monaco Editor Core + type: boolean + default: false + - name: publishMonacoEditor + displayName: 🚀 Publish Editor Core + type: boolean + default: false extends: template: azure-pipelines/npm-package/pipeline.yml@templates parameters: npmPackages: - - name: foobar - testPlatforms: - - name: Linux - nodeVersions: - - 16.14.2 - - name: MacOS - nodeVersions: - - 16.14.2 - - name: Windows - nodeVersions: - - 16.14.2 - testSteps: - - checkout: vscode - - script: dir $(Build.SourcesDirectory) + - name: monaco-editor-core + workingDirectory: $(Build.SourcesDirectory)/dependencies/vscode/out-monaco-editor-core + testPlatforms: [] buildSteps: - - script: dir $(Build.SourcesDirectory) + - script: npm ci + displayName: Install NPM dependencies + + - script: yarn ts-node ./scripts/ci/prepare-monaco-editor-core-stable + displayName: Setup, Build & Test monaco-editor-core + tag: ${{ parameters.quality }} - publishPackage: false - postPublishSteps: - - script: dir . - workingDirectory: $(Build.SourcesDirectory) + publishPackage: ${{ parameters.publishMonacoEditorCore }} + publishRequiresApproval: false + + - name: monaco-editor + workingDirectory: $(Build.SourcesDirectory)/release + testPlatforms: [] + buildSteps: + - script: npm ci + displayName: Install NPM dependencies + + - script: yarn ts-node ./scripts/ci/prepare-monaco-editor-stable + displayName: Setup, Build & Test monaco-editor + + tag: ${{ parameters.quality }} + publishPackage: ${{ parameters.publishMonacoEditor }} + publishRequiresApproval: false diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 280d3a78..00000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,250 +0,0 @@ -name: Publish to npm - -on: - schedule: - - cron: '0 5 * * *' - # enable users to manually trigger with workflow_dispatch - workflow_dispatch: - inputs: - nightly: - description: 'is nightly?' - required: true - default: 'true' -jobs: - publish: - if: ${{ github.repository == 'microsoft/monaco-editor' }} - name: Publish to npm - runs-on: ubuntu-latest - steps: - - uses: actions/setup-node@v2 - with: - node-version: 16 - - - name: (monaco-editor) checkout - uses: actions/checkout@v2 - with: - repository: 'microsoft/monaco-editor' - path: './monaco-editor' - - - name: Compute state - id: state - run: | - echo '::echo::on' - node ./monaco-editor/.github/workflows/publish/computeState.js "${{github.event_name}}" "${{github.event.inputs.nightly}}" - # outputs: dist_tag, version, vscode_branch, skip_monaco_editor_core, skip_monaco_editor - - - name: (vscode) checkout - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - uses: actions/checkout@v2 - with: - repository: 'microsoft/vscode' - ref: ${{ steps.state.outputs.vscode_branch }} - path: './vscode' - - - name: (vscode-loc) checkout - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - uses: actions/checkout@v2 - with: - repository: 'microsoft/vscode-loc' - path: './vscode-loc' - - - name: (vscode) execute `yarn` - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn --frozen-lockfile --network-timeout 180000 - - - name: (vscode) Download Playwright - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: ./vscode - run: yarn playwright-install - - - name: (vscode) Run Hygiene Checks - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn gulp hygiene - - - name: (vscode) Run Valid Layers Checks - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn valid-layers-check - - - name: (vscode) Compile /build/ - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn --cwd build compile - - - name: (vscode) Run eslint - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn eslint - - - name: (vscode) Run Monaco Editor Checks - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn monaco-compile-check - - - name: (vscode) Compile - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn --max_old_space_size=4095 compile - - - name: (vscode) Run Unit Tests (Browser) - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn test-browser --browser chromium - - - name: (vscode) Patch package.json version - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - run: node ./monaco-editor/.github/workflows/publish/setVersion.js ./vscode/build/monaco/package.json ${{ steps.state.outputs.version }} - - - name: (vscode) Editor Distro - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: yarn gulp editor-distro - - - name: Editor ESM sources check - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode/test/monaco' - run: yarn run esm-check - - - name: (vscode) Typings validation prep - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode' - run: mkdir typings-test - - - name: (vscode) Typings validation - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: ./vscode/typings-test - run: | - yarn init -yp - ../node_modules/.bin/tsc --init - echo "import '../out-monaco-editor-core';" > a.ts - ../node_modules/.bin/tsc --noEmit - - - name: (vscode) Package Editor with Webpack - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: ./vscode/test/monaco - run: yarn run bundle-webpack - - - name: (vscode) Compile Editor Tests - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: ./vscode/test/monaco - run: yarn run compile - - - name: (vscode) Run Editor Tests - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - timeout-minutes: 5 - working-directory: ./vscode/test/monaco - run: yarn test - - - name: Set `npm` config - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - run: npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Publish `monaco-editor-core` - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - working-directory: './vscode/out-monaco-editor-core' - run: npm publish --tag ${{ steps.state.outputs.dist_tag }} - - - name: Delete `npm` config - if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }} - run: npm config delete //registry.npmjs.org/:_authToken - - - name: (monaco-editor) Patch package.json version - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - run: node ./monaco-editor/.github/workflows/publish/setVersion.js ./monaco-editor/package.json ${{ steps.state.outputs.version }} - - - name: (monaco-editor) execute `npm ci` (1) - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm ci - - - name: (monaco-editor) execute `npm ci` (2) - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor/webpack-plugin' - run: npm ci - - - name: (monaco-editor) Patch package.json monaco-editor-core dev dependency version - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - run: node ./monaco-editor/.github/workflows/publish/setDevDependencyVersion.js ./monaco-editor/package.json monaco-editor-core ${{ steps.state.outputs.version }} - - - name: (monaco-editor) execute `npm install` to pick up local monaco-editor-core - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm install - - - name: (monaco-editor) Install OS Dependencies for Playwright - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: sudo npm run playwright-install-deps - - - name: (monaco-editor) Check prettier - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run prettier-check - - - name: (monaco-editor) Build - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run release - - - name: (monaco-editor) Run unit tests - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm test - - - name: (monaco-editor) Compile webpack plugin - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run compile --prefix webpack-plugin - - - name: (monaco-editor) Package using webpack plugin - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run package-for-smoketest-webpack - - - name: (monaco-editor) Package using esbuild - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run package-for-smoketest-esbuild - - - name: (monaco-editor) Package using vite - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run package-for-smoketest-vite - - - name: (monaco-editor) Package using parcel - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run package-for-smoketest-parcel --prefix test/smoke/parcel - - - name: (monaco-editor) Run smoke test - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run smoketest - - - name: (monaco-editor) Build website - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor' - run: npm run build-website - - - name: Set `npm` config - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - run: npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Publish `monaco-editor` - if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }} - working-directory: './monaco-editor/release' - run: npm publish --tag ${{ steps.state.outputs.dist_tag }} - - - name: Create Issue On Failure - if: failure() - uses: JasonEtco/create-an-issue@9e6213aec58987fa7d2f4deb8b256b99e63107a2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - filename: ./monaco-editor/.github/publish-failure-issue-template.md diff --git a/.github/workflows/publish/setDevDependencyVersion.js b/.github/workflows/publish/setDevDependencyVersion.js deleted file mode 100644 index c25013ec..00000000 --- a/.github/workflows/publish/setDevDependencyVersion.js +++ /dev/null @@ -1,19 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -//@ts-check - -const fs = require('fs'); - -if (process.argv.length !== 5) { - console.error( - `usage: node setDevDependencyVersion.js ` - ); - process.exit(1); -} - -const packagejson = JSON.parse(fs.readFileSync(process.argv[2]).toString()); -packagejson['devDependencies'][process.argv[3]] = process.argv[4]; -fs.writeFileSync(process.argv[2], JSON.stringify(packagejson, null, '\t') + '\n'); diff --git a/.github/workflows/publish/setVersion.js b/.github/workflows/publish/setVersion.js deleted file mode 100644 index 53d0acdb..00000000 --- a/.github/workflows/publish/setVersion.js +++ /dev/null @@ -1,17 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -//@ts-check - -const fs = require('fs'); - -if (process.argv.length !== 4) { - console.error(`usage: node setVersion.js `); - process.exit(1); -} - -const packagejson = JSON.parse(fs.readFileSync(process.argv[2]).toString()); -packagejson.version = process.argv[3]; -fs.writeFileSync(process.argv[2], JSON.stringify(packagejson, null, '\t') + '\n'); diff --git a/.gitignore b/.gitignore index 77b06aa4..eeb18620 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ **/node_modules/ **/out/ **/release/ +**/dependencies/ /test/manual/generated/** /test/smoke/vite/dist/** /test/smoke/parcel/dist/** diff --git a/package.json b/package.json index d6dddf62..fde0e2f3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "monaco-editor", "version": "0.34.1", - "vscode": "0316a754aa4c25208bef91937efbce2ab1e3ce37", + "vscodeRef": "0316a754aa4c25208bef91937efbce2ab1e3ce37", "private": true, "description": "A browser based code editor", "author": "Microsoft Corporation", diff --git a/scripts/ci/monaco-editor-core.sh b/scripts/ci/monaco-editor-core.sh new file mode 100755 index 00000000..52725a15 --- /dev/null +++ b/scripts/ci/monaco-editor-core.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -e + +# cwd must be the vscode repository. + +yarn --frozen-lockfile --network-timeout 180000 +yarn playwright-install +yarn gulp hygiene +yarn valid-layers-check +yarn --cwd build compile +yarn eslint +yarn monaco-compile-check +yarn --max_old_space_size=4095 compile + +yarn test-browser --browser chromium + +yarn gulp editor-distro +mkdir typings-test + +cd typings-test +yarn init -yp +../node_modules/.bin/tsc --init +echo "import '../out-monaco-editor-core';" > a.ts +../node_modules/.bin/tsc --noEmit +cd .. + +cd test/monaco +yarn run esm-check +yarn run bundle-webpack +yarn run compile +yarn test +cd ../.. + +# npm package is now in dependencies/vscode/out-monaco-editor-core, ready to be published diff --git a/scripts/ci/monaco-editor.sh b/scripts/ci/monaco-editor.sh new file mode 100755 index 00000000..4efd4f74 --- /dev/null +++ b/scripts/ci/monaco-editor.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e + +# execute `npm install` to pick up local monaco-editor-core +npm install +# Install OS Dependencies for Playwright +sudo npm run playwright-install-deps +# Check prettier +npm run prettier-check +# Build +npm run release + +# Run unit tests +npm test + +# Compile webpack plugin +npm run compile --prefix webpack-plugin +# Package using webpack plugin +npm run package-for-smoketest-webpack +# Package using esbuild +npm run package-for-smoketest-esbuild +# Package using vite +npm run package-for-smoketest-vite +# Package using parcel +npm run package-for-smoketest-parcel --prefix test/smoke/parcel + +# Run smoke test +npm run smoketest + +# Build website +npm run build-website + +# npm package is now ready to be published in ./release diff --git a/scripts/ci/prepare-monaco-editor-core-stable.ts b/scripts/ci/prepare-monaco-editor-core-stable.ts new file mode 100755 index 00000000..d6cb240c --- /dev/null +++ b/scripts/ci/prepare-monaco-editor-core-stable.ts @@ -0,0 +1,56 @@ +import { mkdir, rm } from 'fs/promises'; +import { join, resolve } from 'path'; +import { group, gitShallowClone, run, writeJsonFile } from '../lib'; + +const selfPath = __dirname; +const rootPath = join(selfPath, '..', '..'); +const dependenciesPath = join(rootPath, 'dependencies'); +const vscodePath = resolve(dependenciesPath, 'vscode'); +const monacoEditorPackageJsonPath = resolve(rootPath, 'package.json'); + +async function prepareMonacoEditorCoreReleaseStable() { + const monacoEditorPackageJson = require(monacoEditorPackageJsonPath) as { + version: string; + vscodeRef: string; + }; + await prepareMonacoEditorCoreRelease( + monacoEditorPackageJson.version, + monacoEditorPackageJson.vscodeRef + ); + + // npm package is now in dependencies/vscode/out-monaco-editor-core, ready to be published +} + +async function prepareMonacoEditorCoreRelease(version: string, vscodeRef: string) { + await mkdir(vscodePath, { recursive: true }); + + await rm(dependenciesPath, { force: true, recursive: true }); + + await group('Checkout vscode', async () => { + await gitShallowClone(vscodePath, 'https://github.com/microsoft/vscode.git', vscodeRef); + }); + await group('Checkout vscode-loc', async () => { + await gitShallowClone( + // Must be a sibling to the vscode repository + 'dependencies/vscode-loc', + 'https://github.com/microsoft/vscode-loc.git', + 'main' + ); + }); + + await group('Set Version', async () => { + const monacoEditorCorePackageJsonSourcePath = resolve( + vscodePath, + './build/monaco/package.json' + ); + const packageJson = require(monacoEditorCorePackageJsonSourcePath) as { version: string }; + packageJson.version = version; + await writeJsonFile(monacoEditorPackageJsonPath, packageJson); + }); + + await group('Building & Testing', async () => { + await run(resolve(selfPath, './monaco-editor-core.sh'), { cwd: vscodePath }); + }); +} + +prepareMonacoEditorCoreReleaseStable(); diff --git a/scripts/ci/prepare-monaco-editor-stable.ts b/scripts/ci/prepare-monaco-editor-stable.ts new file mode 100755 index 00000000..f01137fb --- /dev/null +++ b/scripts/ci/prepare-monaco-editor-stable.ts @@ -0,0 +1,38 @@ +import { readFile } from 'fs/promises'; +import { join, resolve } from 'path'; +import { group, run, writeJsonFile } from '../lib'; + +const selfPath = __dirname; +const rootPath = join(selfPath, '..', '..'); +const monacoEditorPackageJsonPath = resolve(rootPath, 'package.json'); + +async function prepareMonacoEditorReleaseStable() { + const monacoEditorPackageJson = JSON.parse( + await readFile(monacoEditorPackageJsonPath, { encoding: 'utf-8' }) + ) as { version: string }; + await prepareMonacoEditorRelease(monacoEditorPackageJson.version); + + // npm package is now in ./release, ready to be published +} + +async function prepareMonacoEditorRelease(version: string) { + await group('npm ci', async () => { + await run('npm ci', { cwd: resolve(rootPath, 'webpack-plugin') }); + }); + + await group('Set Version', async () => { + const packageJson = JSON.parse( + await readFile(monacoEditorPackageJsonPath, { encoding: 'utf-8' }) + ) as { version: string; devDependencies: Record }; + packageJson.version = version; + // TODO packageJson.devDependencies['monaco-editor-core'] = version; + + await writeJsonFile(monacoEditorPackageJsonPath, packageJson); + }); + + await group('Building & Testing', async () => { + await run(resolve(selfPath, './monaco-editor.sh'), { cwd: rootPath }); + }); +} + +prepareMonacoEditorReleaseStable(); diff --git a/scripts/lib/index.ts b/scripts/lib/index.ts new file mode 100644 index 00000000..de59ac6f --- /dev/null +++ b/scripts/lib/index.ts @@ -0,0 +1,45 @@ +import { spawn } from 'child_process'; +import { mkdir, writeFile } from 'fs/promises'; + +export interface RunOptions { + cwd: string; +} + +export async function run(command: string, options: RunOptions) { + console.log(`Running ${command} in ${options.cwd}`); + const process = spawn(command, { shell: true, cwd: options.cwd, stdio: 'inherit' }); + return new Promise((resolve, reject) => { + process.on('exit', (code) => { + if (code !== 0) { + reject(new Error(`Command ${command} exited with code ${code}`)); + } else { + resolve(); + } + }); + }); +} + +export async function gitShallowClone(targetPath: string, repositoryUrl: string, ref: string) { + await mkdir(targetPath, { recursive: true }); + const options: RunOptions = { cwd: targetPath }; + await run('git init', options); + await run(`git remote add origin ${repositoryUrl}`, options); + await run(`git fetch --depth 1 origin ${ref}`, options); + await run(`git checkout ${ref}`, options); +} + +export async function group(name: string, body: () => Promise): Promise { + console.log(`##[group]${name}`); + try { + await body(); + } catch (e) { + console.error(e); + throw e; + } finally { + console.log('##[endgroup]'); + } +} + +export async function writeJsonFile(filePath: string, jsonData: unknown): Promise { + await writeFile(filePath, JSON.stringify(jsonData, null, '\t') + '\n'); +}