preface

Guys, this thing really, really works, why do you need automated release scripts? If your current project pushes code like this, you have a big problem:

git add -A
git commit -m "xxx"
git push
Copy the code
  • First, do you need to manually change the version number in package.json before you push the version? Is it a hassle?
  • If you want to tag your code, do you need to manually git tag vXXX and git push origin tag to git repository?
  • If you commit a bug that starts with ‘fix:’ or a new feature that starts with ‘feat:’
  • Also, how do I automatically generate Changelog after changing the COMMIT?
  • The most important thing is how extensible your code can be if you write bash scripts yourself. For example, if I add or subtract a process, you have to change the bash script for the process code, not easily abstract out a configurable process script.

Take a look at this NPM package

Here is a configurable Node release script I wrote myself.

I created a scripts folder at the root of my project and a release.ts script underneath

import defaultRelaseProcess from '@mx-design/release';
defaultRelaseProcess();
Copy the code

package.json

  "scripts": {
    // Don't worry about ts-Node dependencies. The @mx-design/release package will install it for you
    "release": "ts-node ./scripts/release.ts"
  },
   "devDependencies": {
    "@mx-design/release": "^ 1.0.0",},Copy the code

Then the command line interface goes to your project root directory and type:

npm run release
Copy the code

Then your command line interface will display the following: 1, ask you to upgrade the version

As you can see, you can choose whether to upgrade to a major version, a minor version, or any other version, all in accordance with the Semver specification.

If your commit does not conform to the Angular commit specification, an error message will be displayed indicating that you do not conform to the specification and the script will be terminated. (The overall interaction is very comfortable. For example, when you git push, we will show that you are pushing. If the push succeeds, the text being pushed will be overwritten, and the color will be green and the icon of the hook will be displayed.)

The interactive loading is as follows:

If the command is executed incorrectly, the following is displayed (github environment in China is very poor, often git push failure, using VPN is the same) :

Git push success results are as follows:

3. The main process of release here is as follows:

The process includes:

  • Select upgrade Version ->
  • Change package.json version number ->
  • Fill in the COMMIT information (checksum format, do not pass termination) ->
  • Push to repository (push failure will help you roll back the version in package.json) ->
  • Generate the changeLog – >
  • Build package (NPM run build command, so your scripts must have build command, or fail to execute) ->
  • Publish –access=public -> publish –access=public
  • Tag and push to git repository

Custom process

The above procedures are the process sequence of this package, you can set your own order,

import { getNextVersion, gitPush, setChangelog, build, publishNpm, addTag, compose } from '@mx-design/release';

// getNextVersion gets the next version number function
// updateVersion Changes the version number. The return value is used to roll back the version number
// gitPush push code function
// setChangelog Sets the changeLog function
// build executes the NPM run build function
// publish executes NPM publish
// addTag calls the tag function
// compose function combinator

// Using the method, the order of these functions can be changed by itself, or added or subtracted
const middle = [getNextVersion, updateVersion, gitPush, setChangelog, build, publishNpm, addTag];

function execRelease() {
  compose(middle);
}
Copy the code

Seek to build + source code analysis

Any interested students are welcome to join the project at any time. Write your own Github account in the comment area or leave a message on the issue. I will add you to the list of core developers as soon as possible.

There are still a few things missing from this project, such as ESLint, stylelint validation, custom Changelog location, adding unit tests, adding Git Workflow, etc. I don’t have time to do that because I have a lot of work to do this year…

Source code analysis

Contents Meaning:

- Root directory - src-addtag-index. ts // Tag function - build-build. ts // build project function - config // Config folder - functions Tool functions - Contstants constant -gitpush-index.ts // push to git function -publishnpm -index.ts // Publish whole project function -selectNextVersion - Index. ts Select the next version number function - setChangeLog - call changeLog function package.json tsconfig.json... There's nothing to be said for ordinary filesCopy the code

Compose, a core middleware executor, is a middleware composition function that shares data and is inspired by the KOA framework. The code is as follows:

export function compose(middleware) {
  // Share data warehouse, each function can add data to it, all functions can access the data in it
  const otherOptions = {}; 
  // The function emitter, which calls next() after a function has finished executing, executes the next function
  function dispatch(index, otherOptions) {
    // Execute one function at a time from the Middleware middleware until all functions are executed
    if (index == middleware.length) return;
    const currMiddleware = middleware[index];
    // Execute the function, passing in the dispatch of the next function, which has updated the shared data
    currMiddleware((addOptions) = >{ dispatch(++index, { ... otherOptions, ... addOptions }); }, otherOptions).catch((error) = > {
      console.log('💣 failed to publish, cause: ', error);
    });
  }
  dispatch(0, otherOptions);
}
Copy the code

Middleware writing

// Get the version number function, starting with next, to call the next function in middleware
const getNextVersion = async (next) => {
  // _selectNextVersion will see what version of your package.json parameter is
  const nextVersion = await _selectNextVersion();
  // Cache old package.json data in preparation for later rollback versions
  const originPackageJson = getOriginPackageJson();
  // Next incoming data will be stored in the shared data warehouse, which can be accessed by the following functions
  next({
    nextVersion,
    originVersion: originPackageJson.version,
    originPackageJson,
  });
};

// Update the version number method
const updateVersion = async (next, otherOptions) => {
  if(! otherOptions? .nextVersion) {throw new Error('Please pass in package.json new version number');
  }
  // Returns a method to back up the version number for which the originPackageJson data is shared
  // basicCatchError If the command fails to execute, print the failure cause and return false
  const backVersionFn = await _updateVersion(otherOptions.nextVersion, otherOptions.originPackageJson).catch(
    basicCatchError,
  );
  // Share the back version of the function and call it where you need it
  next({ backVersionFn });
};
Copy the code

Case description

compose([getNextVersion, updateVersion])
Copy the code

So compose is called first

  • dispatch(0, otherOptions)
  • 0 represents the first item in the Middleware array for compose’s input
  • OtherOptions represents shared data and is currently an empty object

Next, the first function call

  • getNextVersion((addOptions) => { dispatch(++index, { … otherOptions, … addOptions }); }, otherOptions);
  • Let’s look at the first argument, we wrote it this way
  • const getNextVersion = async (next) => {
  • Next calls dispatch, and index + 1 calls the second function in the Middleware array
  • The second argument to dispatch is to send the data next wants to share

This year, MY main task is to write react PC and mobile component library. Before that, I wrote the CLI packaging and development scaffolding. The article is as follows: juejin.cn/post/707518…

I want to be a core contributor for this project, so I will leave a message directly and tell you about my Github account. I will add you as soon as POSSIBLE. Thank you for clicking star.