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)
Checkout code] Cutting out a new branch of code.
Update package.json] Execute update-version.js in the new branch and pass intag_name
to update our project version number.
Commit changes] Creates a new commit with your customized git config user information.- [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 thepublished
type will trigger. If you want a workflow to run when stable and pre-releases publish, subscribe topublished
instead ofreleased
andprereleased
.
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
- 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
- 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 }}