Add scripts for publishing to VS Code Marketplace

* Simplify command invocations are npm scripts
* Add shortcuts for running these commands from VS Code
* Use shx to run scripts in platform-agnostic manner
* Add scripts to help with packaging and publishing of .vsix
* Add instructions on how to publish
* Clarify how to run on Windows

@W-4162004@
This commit is contained in:
Nick Chen 2017-07-21 16:28:53 -07:00 коммит произвёл GitHub
Родитель 537f7f1cdb
Коммит 13c5f0c27a
17 изменённых файлов: 358 добавлений и 56 удалений

Просмотреть файл

@ -43,6 +43,6 @@ install:
- npm install
script:
- lerna run compile
- lerna run lint
- npm run compile
- npm run lint
# - lerna run test --concurrency 1

43
.vscode/tasks.json поставляемый
Просмотреть файл

@ -4,28 +4,27 @@
"tasks": [
{
"taskName": "Bootstrap",
"command": "lerna",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"args": ["bootstrap"],
"args": ["run", "bootstrap"],
"isBackground": false
},
{
"taskName": "Watch",
"command": "lerna",
"taskName": "Clean",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"args": ["run", "--parallel", "watch"],
"isBackground": true,
"problemMatcher": "$tsc-watch"
"args": ["run", "clean"],
"isBackground": false
},
{
"isBuildCommand": true,
"taskName": "Compile",
"command": "lerna",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"args": ["run", "--stream", "compile"],
"args": ["run", "compile"],
"isBackground": false,
"problemMatcher": {
"owner": "typescript",
@ -39,6 +38,32 @@
"message": 7
}
}
},
{
"taskName": "Lint",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"args": ["run", "lint"],
"isBackground": false
},
{
"isTestCommand": true,
"taskName": "Test",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"args": ["run", "test"],
"isBackground": false
},
{
"taskName": "Watch",
"command": "npm",
"isShellCommand": true,
"showOutput": "silent",
"args": ["run", "watch"],
"isBackground": true,
"problemMatcher": "$tsc-watch"
}
]
}

Просмотреть файл

@ -15,6 +15,26 @@
it will ask you to install them. **Please do so since this includes the
linters and formatters**.
## Pre-requisites for Windows Development
These are instructions for _developing_ the extensions on Windows since there
are some quirkiness with the way Windows behaves. This does not affect the
actual extensions that we distribute.
1. Same as above.
1. You should use Bash Shell instead of Powershell or the Command Prompt.
1. If you want to use the integrated terminal in VS Code, you can see that
following the instructions
[here](https://code.visualstudio.com/docs/editor/integrated-terminal#_windows);
1. You should install VS Code Insiders from
[here](https://code.visualstudio.com/insiders). Without this, you won't be
able to run the end-to-end tests while VS Code is open. You will see an error
of the form "Running extension tests from the command line is currently only
supported if no other instance of Code is running." To circumvent that you
could close VS Code each time you run the tests. Or, you can install the
Insiders version so that it can run the tests in Code while you work in the
Insiders version.
## Structure
### Packages
@ -39,7 +59,7 @@ You would only do this once after you cloned the repository.
You would usually do the following each time you close/reopen VS Code:
1. [Optional] Open the Command Palette > Tasks: Run Task > Bootstrap (this
essentially runs `lerna bootstrap`). This is required if you change the
essentially runs `npm run bootstrap`). This is required if you change the
dependencies in any of the package.json.
1. If you wish to build, you can invoke Command Palette > Build Task
(Ctrl+Shift+B or Cmd+Shift+B on Mac). The errors will show in the Problems
@ -56,9 +76,9 @@ to run and debug extensions.
When you are ready to commit
1. Run `lerna run lint` to run tslint in more thorough mode to identify any
1. Run `npm run lint` to run tslint in more thorough mode to identify any
errors.
1. Some of the items can be fixed using `tstlint --project . fix`. Some you
1. Some of the items can be fixed using `tslint --project . fix`. Some you
might need to fix them manually.
This linting steps should be done later as part of the continuous integration
@ -66,7 +86,9 @@ runs but that is how you would check locally first.
## List of Useful commands
### `lerna bootstrap`
_These commands assume that they are executed from the top-level directory. Internally, they delegate to `lerna` to call them on each npm module in the packages directory._
### `npm run bootstrap`
This bootstraps the packages by issuing an `npm install` on each package and
also symlinking any package that are part of the packages folder.
@ -77,27 +99,27 @@ modules.
If you change the dependencies in your package.json, you will also need to run
this command.
### `lerna run compile`
### `npm run compile`
This runs `npm run compile` on each of the package in packages.
### `lerna run clean`
### `npm run clean`
This run `npm run clean` on each of the package in packages.
### `lerna run --parallel watch`
### `npm run watch`
This runs `npm run watch` on each of the package in packages. The `--parallel`
flag tell it to run each in a separate process so that it won't block the main
thread.
### `lerna run test --concurrency 1`
### `npm run test`
This runs `npm test` on each of the packages. The `--concurrency 1` is essential
for VS Code extension tests since they require an instance of Code to run in.
And, only one instance of that can be running at a single time.
### `lerna run lint`
### `npm run lint`
This runs `npm lint` on each of the packages. If there are no errors/warnings
from tslint, then you get a clean output. But, if they are errors from tslint,

89
docs/publishing.md Normal file
Просмотреть файл

@ -0,0 +1,89 @@
# Introduction
This is a guide for publishing to the Visual Studio Code Marketplace. Most
contributors will not need to worry about publishing. However, it might be
worthwhile familiarizing yourself with the steps in case you need to share the
extensions through the .vsix files.
# Goal
The goal of publishing is to take the extensions under /packages, bundle them as
.vsix files, and push them to the [Visual Studio Code
Marketplace](https://marketplace.visualstudio.com/vscode).
For more information about publishing take a look at
* [Publishing VS Code Extensions](https://code.visualstudio.com/docs/extensions/publish-extension)
* [Managing Extensions](https://code.visualstudio.com/docs/editor/extension-gallery)
# Steps
The scripts/publish.js contains the end-to-end flow. It is possible to run each step manually.
The files under scripts use [shelljs/shx](https://github.com/shelljs/shx) and
[shelljs/shelljs](https://github.com/shelljs/shelljs) to write scripts in a
portable manner across platforms.
## Packaging as .vsix
### Prerequisite
* Lerna is properly installed.
### Steps
1. `npm run bootstrap` to install all the dependencies and to symlink interdependent local modules.
1. `npm run compile` to compile all the TypeScript files.
1. `npm run test` to run all the tests.
1. `lerna publish ...` will increment the version in the individual package.json
to prepare for publication. **This also commits the changes to git and adds a
tag.**
1. `npm run vscode:package` packages _each_ extension as a .vsix.
**At this stage, it is possible to share the .vsix directly for manual installation.**
## Generating SHA256
Due to [vscode-vsce#191](https://github.com/Microsoft/vscode-vsce/issues/191)
the .vsix are neither signed nor verified. To ensure that they have not been
tampered with, we generate a SHA256 of the contents and publish that to
https://developer.salesforce.com/media/vscode/SHA256
### Prerequisite
* You have access to our S3 bucket at s3://dfc-data-production/media/vscode
* You have the [AWS CLI](https://aws.amazon.com/cli/) installed and configured
via `aws configure` or have the `AWS_ACCESS_KEY_ID` and
`AWS_SECRET_ACCESS_KEY` exported as environment variables.
### Steps
1. `npm run vscode:sha256` will compute the SHA256 for the .vsix generated in
the previous stage.
1. The SHA256 are appended to the top-level SHA256 file.
1. This file is then copied over to our S3 bucket.
1. Finally the file is added to git so that it can be committed.
## Pushing .vsix to Visual Studio Marketplace
### Prerequisite
* You have a personal access token that for the salesforce publisher id that is
exported as `VSCE_PERSONAL_ACCESS_TOKEN`.
* Or, you have vsce installed and configured with the salesforce publisher id.
### Steps
1. `npm run vscode:publish` takes the .vsix that you had _before_ and uploads
it to the Visual Studio Code Marketplace.
It's **crucial** that you publish the .vsix that you had before so that the
SHA256 match. If you were to repackage, the SHA256 would be different.
# Tips
1. After publishing, you will need to run `npm run bootstrap` again to continue
development. This is because the `npm run vscode:package` step does a `npm
prune --production`. This is required due to the way Lerna does symlinking.
See [vscode-vsce#52](https://github.com/Microsoft/vscode-vsce/issues/52) for
more information.

Просмотреть файл

@ -1,7 +1,7 @@
{
"lerna": "2.0.0-rc.5",
"lerna": "2.0.0",
"packages": [
"packages/*"
],
"version": "0.1.0"
"version": "0.2.0"
}

Просмотреть файл

@ -1,11 +1,23 @@
{
"devDependencies": {
"lerna": "^2.0.0-rc.5",
"lerna": "2.0.0",
"shx": "^0.2.2",
"tslint": "5.5.0",
"typescript": "2.4.0",
"tslint": "5.5.0"
"vsce": "1.29.0"
},
"scripts": {
"postinstall": "lerna bootstrap"
"postinstall": "lerna bootstrap",
"bootstrap": "lerna bootstrap",
"clean": "lerna run clean",
"compile": "lerna run --stream compile",
"lint": "lerna run lint",
"publish": "node scripts/publish.js",
"test": "lerna run test --concurrency 1",
"vscode:package": "lerna run vscode:package --concurrency 1",
"vscode:sha256": "lerna run vscode:sha256 --concurrency 1",
"vscode:publish": "lerna run vscode:publish --concurrency 1",
"watch": "lerna run --parallel watch"
},
"repository": {
"type": "git",

Просмотреть файл

@ -2,10 +2,12 @@
"name": "@salesforce/salesforcedx-utils-vscode",
"displayName": "SFDX Utilities for VS Code",
"description": "Provides utilies to interface the SFDX libraries with VS Code",
"version": "0.1.0",
"version": "0.2.0",
"publisher": "salesforce",
"license": "MIT",
"categories": ["Other"],
"categories": [
"Other"
],
"dependencies": {
"rxjs": "^5.4.1",
"tree-kill": "^1.1.0"
@ -23,8 +25,8 @@
"compile": "tsc -p ./",
"lint": "tslint --project .",
"watch": "tsc -watch -p .",
"clean": "rm -rf node_modules && rm -rf out",
"test": "node ./node_modules/.bin/_mocha --recursive out/test",
"clean": "shx rm -rf node_modules && shx rm -rf out",
"test": "./node_modules/.bin/_mocha --recursive out/test",
"coverage": "./node_modules/.bin/nyc npm test"
},
"main": "./out/src/"

Просмотреть файл

@ -8,11 +8,13 @@
"color": "#ECECEC",
"theme": "light"
},
"version": "0.1.0",
"version": "0.2.0",
"publisher": "salesforce",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"categories": ["Debuggers"]
"categories": [
"Debuggers"
]
}

Просмотреть файл

@ -8,13 +8,15 @@
"color": "#ECECEC",
"theme": "light"
},
"version": "0.1.0",
"version": "0.2.0",
"publisher": "salesforce",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"categories": ["Languages"],
"categories": [
"Languages"
],
"devDependencies": {
"@types/chai": "^4.0.0",
"@types/mocha": "2.2.38",
@ -28,14 +30,19 @@
},
"scripts": {
"vscode:prepublish": "npm prune --production",
"vscode:package": "vsce package",
"vscode:sha256": "node ../../scripts/generate-sha256.js >> ../../SHA256",
"vscode:publish": "node ../../scripts/publish-vsix.js",
"compile": "tsc -p ./",
"lint": "tslint --project .",
"watch": "tsc -watch -p .",
"clean": "rm -rf node_modules && (cd out && find . \\! -name 'apex-jorje-lsp.jar' -delete)",
"clean": "shx rm -rf node_modules && cd out && node ../../../scripts/clean-all-but-jar.js",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "node ./node_modules/vscode/bin/test"
},
"activationEvents": ["workspaceContains:sfdx-project.json"],
"activationEvents": [
"workspaceContains:sfdx-project.json"
],
"main": "./out/src",
"contributes": {
"configuration": {
@ -43,7 +50,10 @@
"title": "%configuration_title%",
"properties": {
"salesforcedx-vscode-apex.java.home": {
"type": ["string", "null"],
"type": [
"string",
"null"
],
"default": null,
"description": "%java_home_description%"
}
@ -52,8 +62,14 @@
"languages": [
{
"id": "apex",
"aliases": ["Apex", "apex"],
"extensions": [".cls", ".trigger"],
"aliases": [
"Apex",
"apex"
],
"extensions": [
".cls",
".trigger"
],
"configuration": "./syntaxes/apex.configuration.json"
}
],
@ -66,7 +82,7 @@
]
},
"dependencies": {
"@salesforce/salesforcedx-utils-vscode": "0.1.0",
"@salesforce/salesforcedx-utils-vscode": "0.2.0",
"expand-home-dir": "0.0.3",
"find-java-home": "0.2.0",
"path-exists": "3.0.0",

Просмотреть файл

@ -8,15 +8,17 @@
"color": "#ECECEC",
"theme": "light"
},
"version": "0.1.0",
"version": "0.2.0",
"publisher": "salesforce",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"categories": ["Other"],
"categories": [
"Other"
],
"dependencies": {
"@salesforce/salesforcedx-utils-vscode": "0.1.0",
"@salesforce/salesforcedx-utils-vscode": "0.2.0",
"rxjs": "^5.4.1"
},
"devDependencies": {
@ -33,11 +35,14 @@
"vscode": "1.1.2"
},
"scripts": {
"vscode:prepublish": "tsc -p ./",
"vscode:prepublish": "npm prune --production",
"vscode:package": "vsce package",
"vscode:sha256": "node ../../scripts/generate-sha256.js >> ../../SHA256",
"vscode:publish": "node ../../scripts/publish-vsix.js",
"compile": "tsc -p ./",
"lint": "tslint --project .",
"watch": "tsc -watch -p .",
"clean": "rm -rf node_modules && rm -rf out",
"clean": "shx rm -rf node_modules && shx rm -rf out",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "node ./node_modules/vscode/bin/test"
},

Просмотреть файл

@ -8,13 +8,15 @@
"color": "#ECECEC",
"theme": "light"
},
"version": "0.1.0",
"version": "0.2.0",
"publisher": "salesforce",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"categories": ["Languages"],
"categories": [
"Languages"
],
"devDependencies": {
"@types/chai": "^4.0.0",
"@types/mocha": "2.2.38",
@ -27,11 +29,14 @@
"vscode": "1.1.2"
},
"scripts": {
"vscode:prepublish": "tsc -p ./",
"vscode:prepublish": "npm prune --production",
"vscode:package": "vsce package",
"vscode:sha256": "node ../../scripts/generate-sha256.js >> ../../SHA256",
"vscode:publish": "node ../../scripts/publish-vsix.js",
"compile": "tsc -p ./",
"lint": "tslint --project .",
"watch": "tsc -watch -p .",
"clean": "rm -rf node_modules && rm -rf out",
"clean": "shx rm -rf node_modules && shx rm -rf out",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "node ./node_modules/vscode/bin/test"
},

Просмотреть файл

@ -8,13 +8,15 @@
"color": "#ECECEC",
"theme": "light"
},
"version": "0.1.0",
"version": "0.2.0",
"publisher": "salesforce",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"categories": ["Languages"],
"categories": [
"Languages"
],
"devDependencies": {
"@types/chai": "^4.0.0",
"@types/mocha": "2.2.38",
@ -27,11 +29,14 @@
"vscode": "1.1.2"
},
"scripts": {
"vscode:prepublish": "tsc -p ./",
"vscode:prepublish": "npm prune --production",
"vscode:package": "vsce package",
"vscode:sha256": "node ../../scripts/generate-sha256.js >> ../../SHA256",
"vscode:publish": "node ../../scripts/publish-vsix.js",
"compile": "tsc -p ./",
"lint": "tslint --project .",
"watch": "tsc -watch -p .",
"clean": "rm -rf node_modules && rm -rf out",
"clean": "shx rm -rf node_modules && shx rm -rf out",
"postinstall": "node ./node_modules/vscode/bin/install",
"test": "node ./node_modules/vscode/bin/test"
},
@ -39,7 +44,10 @@
"languages": [
{
"id": "html",
"extensions": [".page", ".component"]
"extensions": [
".page",
".component"
]
}
]
}

Просмотреть файл

@ -2,19 +2,27 @@
"preview": true,
"name": "salesforcedx-vscode",
"displayName": "Visual Studio Code Extension Pack for Salesforce DX",
"description": "Collection of extension for Salesforce DX",
"description": "Collection of extensions for Salesforce DX",
"icon": "images/icon.png",
"galleryBanner": {
"color": "#ECECEC",
"theme": "light"
},
"version": "0.1.0",
"version": "0.2.0",
"publisher": "salesforce",
"license": "MIT",
"engines": {
"vscode": "^1.13.0"
},
"categories": ["Extension Packs"],
"scripts": {
"vscode:prepublish": "npm prune --production",
"vscode:package": "vsce package",
"vscode:sha256": "node ../../scripts/generate-sha256.js >> ../../SHA256",
"vscode:publish": "node ../../scripts/publish-vsix.js"
},
"categories": [
"Extension Packs"
],
"extensionDependencies": [
"salesforce.salesforcedx-vscode-apex",
"salesforce.salesforcedx-vscode-core",

7
scripts/clean-all-but-jar.js Executable file
Просмотреть файл

@ -0,0 +1,7 @@
#!/usr/bin/env node
const shell = require('shelljs');
// Removes all files but .jar files at the top-level
shell.rm('-rf', shell.ls().filter(file => !file.match(/\.jar$/)));

Просмотреть файл

@ -0,0 +1,19 @@
#!/usr/bin/env node
const shell = require('shelljs');
// Generate the SHA256 for the .vsix that matches the version in package.json
const packageVersion = JSON.parse(shell.cat('package.json')).version;
const vsix = shell.ls().filter(file => file.match(`-${packageVersion}.vsix`));
if (!vsix.length) {
shell.error('No VSIX found matching the requested version in package.json');
shell.exit(1);
}
if (/win32/.test(process.platform)) {
shell.exec(`CertUtil -hashfile ${vsix} SHA256`);
} else {
shell.exec(`shasum -a 256 ${vsix}`);
}

24
scripts/publish-vsix.js Normal file
Просмотреть файл

@ -0,0 +1,24 @@
#!/usr/bin/env node
const shell = require('shelljs');
// Publishes the .vsix that matches the version in package.json
const packageVersion = JSON.parse(shell.cat('package.json')).version;
const vsix = shell.ls().filter(file => file.match(`-${packageVersion}.vsix`));
if (!vsix.length) {
shell.error('No VSIX found matching the requested version in package.json');
shell.exit(1);
}
const vsce = '../../node_modules/.bin/vsce';
const VSCE_PERSONAL_ACCESS_TOKEN = process.env['VSCE_PERSONAL_ACCESS_TOKEN'];
if (VSCE_PERSONAL_ACCESS_TOKEN) {
shell.exec(
`${vsce} publish --pat ${VSCE_PERSONAL_ACCESS_TOKEN} --packagePath ${vsix}`
);
} else {
// Assume that one has already been configured
shell.exec(`${vsce} publish --packagePath ${vsix}`);
}

58
scripts/publish.js Normal file
Просмотреть файл

@ -0,0 +1,58 @@
#!/usr/bin/env node
const shell = require('shelljs');
shell.set('-e');
shell.set('+v');
/*
* Assumptions:
* 0. The script is running locally - it's not optimized for Travis workflow
* yet.
* 1. The script is running in the right branch.
* 2. The script is running in a clean environment - all changes have been
* committed.
*/
// Bootstrap
shell.exec('npm run bootstrap');
// Compile
shell.exec('npm run compile');
// Test
shell.exec('npm run test');
// lerna publish
// --skip-npm to increment the version number in all packages but not publish to npmjs
// This will still make a commit in Git with the tag of the version used
const nextVersion = process.env['VERSION_INCREMENT'];
if (nextVersion) {
shell.exec(
`lerna publish --force-publish --exact --repo-version ${nextVersion} --yes --skip-npm`
);
} else {
shell.exec(
'lerna publish --force-publish --exact --cd-version minor --yes --skip-npm'
);
}
// Generate the .vsix files
shell.exec(`npm run vscode:package`);
// Generate the SHA256 and append to the file
shell.exec(`npm run vscode:sha256`);
// Push the SHA256 to AWS
shell.exec('aws s3 cp SHA256 s3://dfc-data-production/media/vscode/SHA256');
// Add SHA256 to git
shell.exec(`git add SHA256`);
// Publish to VS Code Marketplace
shell.exec(`npm run vscode:publish`);
// Perform these steps manually for now
// Git commit
// shell.exec(`git commit -m "Updated SHA256"`);
// Push back to GitHub
//shell.exec(`git push`);