Просмотр исходного кода

chore: Document release process

Michael Bromley 6 лет назад
Родитель
Сommit
59e8de338e
4 измененных файлов с 49 добавлено и 23 удалено
  1. 21 0
      README.md
  2. 2 3
      package.json
  3. 1 1
      scripts/changelogs/commit.hbs
  4. 25 19
      scripts/changelogs/generate-changelog.ts

+ 21 - 0
README.md

@@ -107,8 +107,29 @@ The Admin UI has unit tests which are run with `yarn test:admin-ui`.
 
 Unit tests are co-located with the files which they test, and have the suffix `.spec.ts`.
 
+### Release Process
+
+All packages in this repo are released at every version change (using [Lerna's fixed mode](https://github.com/lerna/lerna#fixedlocked-mode-default)). This simplifies both the development (tracking multiple disparate versions is tough) and also the developer experience for users of the framework (it is simple to see that all packages are up-to-date and compatible).
+
+To make a release:
+
+##### 1. `yarn publish-release`
+
+This will first build all packages to ensure the distributed files are up to date.
+
+Next it will run `lerna publish` which will prompt for which version to update to. Although we are using [conventional commits](https://www.conventionalcommits.org), the version is not automatically being calculated from the commit messages. Therefore the next version should be manually selected. 
+
+This command will also create changelog entries for this release.
+
+##### 2. `git push origin master --follow-tags`
+
+The reason we do not rely on Lerna to push the release to Git is that this repo has a lengthy pre-push hook which runs all tests and builds the admin ui. This long wait then invalidates the npm OTP and the publish will fail. So the solution is to publish first and then push.
+
+
 ## User Guide
 
+TODO: Move this info to the docs
+
 ### Localization
 
 Vendure server will detect the most suitable locale based on the `Accept-Language` header of the client.

+ 2 - 3
package.json

@@ -28,9 +28,8 @@
     "test:e2e": "jest --config packages/core/e2e/config/jest-e2e.json --runInBand",
     "test:admin-ui": "cd admin-ui && yarn test --watch=false --browsers=ChromeHeadlessCI --progress=false",
     "build": "lerna run build",
-    "generate-changelog": "ts-node scripts/changelogs/changelogs.ts",
-    "bump-version": "lerna version -m \"chore: Publish %s\" --no-push",
-    "publish": "yarn build && lerna publish --exact -m \"chore: Publish %s release\" --no-git-tag-version"
+    "generate-changelog": "ts-node scripts/changelogs/generate-changelog.ts",
+    "publish-release": "yarn build && lerna publish -m \"chore: Publish %s\" --no-push"
   },
   "devDependencies": {
     "@commitlint/cli": "^7.6.1",

+ 1 - 1
scripts/changelogs/commit.hbs

@@ -1,4 +1,4 @@
-* {{subject}}
+* {{#if scope}}**{{scope}}** {{/if}}{{subject}}
 
 {{~!-- commit link --}} {{#if @root.linkReferences~}}
   ([{{hash}}](

+ 25 - 19
scripts/changelogs/changelogs.ts → scripts/changelogs/generate-changelog.ts

@@ -5,24 +5,24 @@ import { addStream } from './add-stream';
 // tslint:disable-next-line:no-var-requires
 const conventionalChangelogCore = require('conventional-changelog-core');
 
-type PackageDef = { name: string | string[]; path: string; };
-
 /**
  * The types of commit which will be included in the changelog.
  */
-const TYPES_TO_INCLUDE = ['feat', 'fix'];
+const VALID_TYPES = ['feat', 'fix'];
 
 /**
- * Define which packages to create changelog entries for. The `name` property should correspond to the
- * "scope" as used in the commit message.
+ * Define which packages to create changelog entries for.
  */
-const PACKAGES: PackageDef[] = [
-    { name: ['admin-ui-plugin', 'admin-ui'], path: path.join(__dirname, '../../packages/admin-ui-plugin') },
-    { name: ['asset-server', 'asset-server-plugin'], path: path.join(__dirname, '../../packages/asset-server-plugin') },
-    { name: 'common', path: path.join(__dirname, '../../packages/common') },
-    { name: 'core', path: path.join(__dirname, '../../packages/core') },
-    { name: 'create', path: path.join(__dirname, '../../packages/create') },
-    { name: ['email-plugin', 'email'], path: path.join(__dirname, '../../packages/email-plugin') },
+const VALID_SCOPES: string[] = [
+    'admin-ui-plugin',
+    'admin-ui',
+    'asset-server',
+    'asset-server-plugin',
+    'common',
+    'core',
+    'create',
+    'email-plugin',
+    'email',
 ];
 
 const mainTemplate = fs.readFileSync(path.join(__dirname, 'template.hbs'), 'utf-8');
@@ -31,21 +31,21 @@ const commitTemplate = fs.readFileSync(path.join(__dirname, 'commit.hbs'), 'utf-
 generateChangelogForPackage();
 
 /**
- * Generates changelog entries for the given package based on the conventional commits data.
+ * Generates changelog entries based on the conventional commits data.
  */
 function generateChangelogForPackage() {
     const changelogPath = path.join(__dirname, '../../CHANGELOG.md');
     const inStream = fs.createReadStream(changelogPath, { flags: 'a+' });
     const tempFile = path.join(__dirname, `__temp_changelog__`);
-    conventionalChangelogCore({
+    conventionalChangelogCore(
+        {
             transform: (commit: any, context: any) => {
-                const includeCommit = TYPES_TO_INCLUDE.includes(commit.type);
+                const includeCommit = VALID_TYPES.includes(commit.type) && scopeIsValid(commit.scope);
                 if (includeCommit) {
                     return context(null, commit);
                 } else {
                     return context(null, null);
                 }
-
             },
             releaseCount: 1,
             outputUnreleased: true,
@@ -62,7 +62,8 @@ function generateChangelogForPackage() {
                 context.commitGroups.forEach(addHeaderToCommitGroup);
                 return context;
             },
-        })
+        },
+    )
         .pipe(addStream(inStream))
         .pipe(fs.createWriteStream(tempFile))
         .on('finish', () => {
@@ -74,8 +75,13 @@ function generateChangelogForPackage() {
         });
 }
 
-function scopeMatchesName(scope: string, name: string | string[]): boolean {
-    return Array.isArray(name) ? name.includes(scope) : scope === name;
+function scopeIsValid(scope: string): boolean {
+    for (const validScope of VALID_SCOPES) {
+        if (scope.includes(validScope)) {
+            return true;
+        }
+    }
+    return false;
 }
 
 /**