Go to -> my original blog

Design ideas

After the company manually NPM publish, it is troublesome to work, which involves sending packets in different NPM warehouses, organizing update logs, pushing update notifications in groups, etc. Because I’m lazy, I decided to write a gadget to help me do all of this.

These transactions contain

Automatic upgrade version number

The original design here is to directly perform automatic incrementation of the small version, but it feels not smart enough. If the user upgrades the large version, he has to manually change it, so the user is supported to upload the version number by himself. For example:

NPM run release [version number]Copy the code

After calculating the new version number, reset package.json and directly type git tag, which we will use later when generating Changelog.

Publish to multiple repositories

Without scope, you can simply run the command NPM publish –registry= XXXX. This can be complicated if you need to publish under a scope in multiple NPM repositories.

npm scope

A Registry can have multiple scopes, but a scope can only correspond to one Registry, that is, if there is a package named @xx/yy to be published to multiple repositories, the scope must be reset constantly. So how do you automate this part.

The design data structure is as follows:

 publish: {
    dir: 'dist',
    registries: [
      { url: 'http://localhost:4873/' },
      { url: 'http://npm.yonghui.cn/repository/yh-npm/', scope: '@yh' },
    ],
  }
Copy the code

The upload work in this phase includes modifying package.json according to scope, uploading to different NPM repositories, counting the upload results, and collecting error data. I thought it would be ok if I wrote promises. The catch, however, is that because the modified package.json is a piece of data, the promise is executed synchronously during the instantiation phase, so the package.json is read and written at the same time.

This problem was later solved by writing it as a generator, as shown in the following example:

const p1 = () = >
    new Promise((resolve, reject) = > {
        setTimeout(() = > {
            fs.writeFileSync('./log.txt'.'aaa')
            resolve(1)},2000)})const p2 = () = >
    new Promise((resolve, reject) = > {
        setTimeout(() = > {
            fs.writeFileSync('./log.txt'.'bbbbbbb')
            resolve(2)},1000)})const ps = [p1, p2]

function* gent() {
    const f1 = yield p1()
    const f2 = yield p2()
    console.log(f1, f2)
}

function run(gen) {
    const g = gen()
    function next(data) {
        const res = g.next(data)
        if (res.done) return res.value
        res.value.then((data) = > {
            next(data)
        })
    }
    next()
}

run(gent)
Copy the code

Get Git commit information

git log

Running Git log directly will print a lot of unnecessary information, we want to generate changelog only by paying attention to the commit title (the content of the commit), so the command line

git log --pretty=format:%s
Copy the code

Format is followed by a placeholder for the desired content (see personalizing the output format of your Git Log), %s for the commit title, and %b for the commit content.

How to hook a Git log to a version number?

The above command can get all commit records, but these commit records are not related to the package version number, as follows:

$git log --pretty=format:%s $git log --pretty=format:%s Table component Supports tableAction Feat: Table component Add TableStatus component feat: Add checksum feat: add input checksumCopy the code

So how do you get the commit information for the latest version?

git tag

Get the Git log between two tags (that is, the content reference document for each tag update)

git log [oldTag].. [newTag] git log 0.1.5... 0.1.6Copy the code

With formatting, only the commit header and commit information are printed, as shown below

The git log 0.1.5.. S__ 0.1.6 - pretty = format: % % aiCopy the code

Final print

2. Tslint support in patchConstant __2021-06-24 15:08:32 +0800 feat: Table component support tableAction__2021-06-24 14:23:55 +0800 Feat: Table component Add TableStatus component __2021-06-24 14:11:27 +0800Copy the code

With the updated version number, time, and content, we can collect and process it into a document

Generate the changelog

I will not elaborate on how to process the information into md format.

To give an example of what was described as conventional commits, we would classify commit messages according to the relative flag in the commit message. Only the commit types are filtered for feat and fix, and the rest are divided into Other, because package users are most concerned with new features and bug fixes. (Also, bring the version number and release date.)

This process is the process of processing text, and the final generated text format is as follows:

# # FIX BUGS = = = = = = = = = = = = = = = = = = * repair status in detail tableAction and tableStatus type extension number # # FEATURE = = = = = = = = = = = = = = = = = = * Table component support tableAction * Table component add tableStatus componentCopy the code

Insert the readme

You can put the changelog generated by the above content in a new page, or insert it into the package home page, which is ok, considering that if you take out a single page, the file will still be put in Git, but Git may be a private repository, so it may not be visible to the package user. So the final solution is inserted into the README.

The idea of this part is to read the string, find the inserted flag, and insert it into the specified position.

Trigger webhook

Then is to send webhook, here is to use the flying book robot, according to the document to send HTTPS request is OK! The effect is as follows: