For the node.js part, we have to have a script that changes the repository code left for ci to execute


We first need to add a update-version.js script to the ./script/.. directory in the project directory


//update-version.js

const path = require('path');
const fs = require('fs');
const newVersion = process.argv[2].replace(/^v/, '');; 

if (!newVersion) {
 
    process.exit(1);

}
 

const currentDirectory = process.cwd();

 
const packageJsonPath = path.join(currentDirectory, 'package.json');
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8');
const packageJson = JSON.parse(packageJsonContent);
const currentVersion = packageJson.version;

 

packageJson.version = newVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
 


Next, the package.json script can be configured to trigger the change version number script directly from npm run version <version> . Of course, this assumes that you want to keep this script available to developers on the command line.


{

    "name": "version workflow",
    "version": "1.0.0",
    "description": "version update demo",
    "main": "index.js",
    "scripts": {
        //...
        "version": "node ./scripts/update-version.js"
    },
    //...

}


CI :How do I get the behavior of the release package to synchronize directly with the version number in the code repository?


How to synchronize the behavior of package releases with the version number in the repository? Here we use the github action provided by github, the specific operation and syntax can check out the official documentation, this article will not be too much to expand.


We need to add a file with the following path to the repository root directory .github/workflows/update-action.yml


name: Update Package Version

on:
  release:
    types: [released]

jobs:
  update:
    runs-on: ubuntu-latest
    steps:

      - name: Checkout code
        uses: actions/checkout@v3

     - name: Update package.json
       run: |
         node ./scripts/update-version.js ${{ github.event.release.tag_name }}
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

     - name: Commit changes
       run: |
         git config user.name "Your github name"
         git config user.email "your github email"
         git add .
         git commit -m "Update version to ${{ github.event.release.tag_name }} for release ${{ github.ref }}"

     - name: Push changes
       uses: ad-m/github-push-action@master
       with:
         github_token: ${{ secrets.GITHUB_TOKEN }}


We’ve added an update job to the released state in the release hook. It will do the following things (which are in the script step)


  1. Checkout code] Cutting out a new branch of code.

  2. Update package.json] Execute update-version.js in the new branch and pass in tag_name to update our project version number.

  3. Commit changes] Creates a new commit with your customized git config user information.
  4.  [Push changes] Push changes back to the trunk.


ps: Properly we should execute our job at prereleased before posting the execution action but the reason why this is not used is as follows:

   The prereleased type will not trigger for pre-releases published from draft releases, but the published type will trigger. If you want a workflow to run when stable and pre-releases publish, subscribe to published instead of released and prereleased.


When this script is pushed, it executes the release and then automatically updates the version without having to be concerned about this version modification issue. You will get the following effect.

 Fill in the correct tag in your repository’s publish screen and publish it!

 Trigger update job Change completed

 The pitfalls you’re likely to encounter the most

  1.  action Failed to execute

Process completed with exit code 129." Node.js 12 actions are deprecated. Please update the following actions to use Node.js 16: actions/checkout@v2. For more information, see https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/.


This is due to a mismatch between the nodejs version of the default action job execution environment and the scripts executed in the actions package, so be sure to use checkout@v3 version actions/checkout@v3

  1.  Problems caused by various unfamiliar action syntax values

 What can be optimized


There’s still a problem with this process of posting our previous commits, you’ll always have a more advanced commit hash after your posting tag


So the action still needs to be optimized, that is, synchronized updates. tag hash

name: Update Package Version

on:
  release:
    types: [released]

jobs:
  update:
    runs-on: ubuntu-latest
    steps:

      - name: Checkout code
        uses: actions/checkout@v3

     - name: Update package.json
       run: |
         node ./scripts/update-version.js ${{ github.event.release.tag_name }}
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

     - name: Commit changes
       run: |
         git config user.name "Your github name"
         git config user.email "your github email"
         git add .
         git commit -m "Update version to ${{ github.event.release.tag_name }} for release ${{ github.ref }}"
         git_hash=$(git rev-parse --short HEAD)

     - name: Push changes
       uses: ad-m/github-push-action@master
       with:
         github_token: ${{ secrets.GITHUB_TOKEN }}

    - name: Tag Push changes
      run: |
        git tag -f ${{ github.event.release.tag_name }} $git_hash
        git push --force origin ${{ github.event.release.tag_name }}
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


The Tag Push changes step has been added compared to the previous version, and at the end of the process, we get the $git_hash generated by this version update and force it to be updated to the tag of the release.

 Let’s see the effect


Finally we look at the tag hash in the release management to get it right!

 Areas that can be re-optimized


Now we still have a problem, that is, every time we execute the Commit changes step, git config user.name "Your github name" git config user.email "your github email" is written to dead, we can read the current user account and mailbox information based on some predefined environment variables in GitHub Actions. You can get the user account of the currently executing Actions from ${{ env.GITHUB_ACTOR }} and the user email of the currently executing Actions from ${{ env.GITHUB_ACTOR }}@users.noreply.github.com (this is a noreply email address, which is used for GitHub notifications, and cannot be sent as an email). Note that this email may not be the user’s real email, but may be the default GitHub email.


If you need to get the real email address of your current GitHub account, you can query it via the GitHub REST API, see the official documentation:


This way we need to add another Set Git user step before Commit Changes

- name: Set Git user
  env:
    GITHUB_ACTOR: ${{ github.actor }}
    GITHUB_EMAIL: ${{ github.actor }}@users.noreply.github.com
  run: |
    git config --global user.name "${{ env.GITHUB_ACTOR }}"
    git config --global user.email "${{ env.GITHUB_EMAIL }}"


So our final Github action script looks like this


name: Update Package Version

on:
  release:
    types: [released]

jobs:
  update:
    runs-on: ubuntu-latest
    steps:

      - name: Checkout code
        uses: actions/checkout@v3

     - name: Update package.json
       run: |
         node ./scripts/update-version.js ${{ github.event.release.tag_name }}
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    
     - name: Set Git user
       env:
         GITHUB_ACTOR: ${{ github.actor }}
         GITHUB_EMAIL: ${{ github.actor }}@users.noreply.github.com
       run: |
         git config --global user.name "${{ env.GITHUB_ACTOR }}"
         git config --global user.email "${{ env.GITHUB_EMAIL }}"
 
     - name: Commit changes
       run: |
         git add .
         git commit -m "Update version to ${{ github.event.release.tag_name }} for release ${{ github.ref }}"
         git_hash=$(git rev-parse --short HEAD)

     - name: Push changes
       uses: ad-m/github-push-action@master
       with:
         github_token: ${{ secrets.GITHUB_TOKEN }}

    - name: Tag Push changes
      run: |
        git tag -f ${{ github.event.release.tag_name }} $git_hash
        git push --force origin ${{ github.event.release.tag_name }}
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

By lzz

Leave a Reply

Your email address will not be published. Required fields are marked *