Bitbucket 在管道执行期间将内部版本号附加到 package.json

Bitbucket Append build number to package.json during pipeline execution

我在 Bitbucket 存储库上有一个 Angular 项目。我创建了这个在 AWS S3 上部署应用程序并使 CloudFront 分配失效的管道。 一切正常。我想将内部版本号添加到已发布的版本中,以便不仅了解应用程序的版本,还了解生成它的内部版本。

image: cypress/browsers:node14.17.0-chrome88-ff89
options:
  max-time: 120

pipelines:
  branches:   
    master:
      - step:
          runs-on:
            - 'self.hosted'
            - 'linux'
          size: 4x
          caches:
            - node          
          script:
            - npm install
            - npm install -g @angular/cli
            - npm run build-stage --progress=false
          artifacts:
            - dist/**
      - step:
          runs-on:
            - 'self.hosted'
            - 'linux'
          size: 4x
          name: Deploy on AWS S3 and CloudFront invalidation
          deployment: staging
          script:
            - pipe: atlassian/aws-s3-deploy:1.1.0
              variables:
                AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
                AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY               
                S3_BUCKET: 'xxxxxxx/dist'
                LOCAL_PATH: 'dist'
                DELETE_FLAG: 'true'
                DEBUG: 'true'
            - pipe: atlassian/aws-cloudfront-invalidate:0.6.0
              variables:
                AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
                AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY                
                DISTRIBUTION_ID: "xxxxxxx"
                PATHS: "/*"

definitions:
  caches:
    npm: $HOME/.npm
    cypress: $HOME/.cache/Cypress

这是我 package.json:

的开头部分
{
  "name": "myApp",
  "version": "22.01.36"
}

我希望向用户显示的最终版本是 22.01.36bxx(其中 xx 是 Bitbucket 内部版本号)。 我想我只需要在 package.json 文件中进行替换。您对完成“任务”有什么建议吗?

Bitbucket Pipelines yml 文件只是 运行ning Bash/shell Linux Docker 机器上的命令。所以你可以使用正常的 Bash 命令,比如 and , to do a "find and replace" inside a JSON text file.

1。生成正确的正则表达式

我们需要编写一个表达式来搜索文件中的文本 "version": "dd.dd.dd" 并将其替换为 "version": "dd.dd.ddb123" ,其中 "d" 是来自 0-9 的数字.

使用https://regex101.com to write and test a regex that does this. Here's a working expression and demo and an explanation: https://regex101.com/r/sRviUF/2

  • 正则表达式: ("version".*:.*"\d.*(?="))
  • 替换: b123

解释:

  • () = 将找到的文本捕获为第 1 组,稍后将其用作 substitution/replacement
  • "version".*:.*" = 查找字符串 "version":",冒号前后允许有 0 个或更多空格 :
  • \d.*(?=") = 查找单个数字 0-9,然后查找任何字符。然后使用 Positive Lookahead (?=") 在下一个语音标记字符 "
  • 之前停止捕获
  • b123 = 替换为捕获的组 1,然后添加 "b" 然后添加数字 123.

2。写一个Bash命令到运行一个文件的正则表达式,搜索和替换

在 Linux 或 MacOS 终端上测试和练习,或使用 Linux Bash Shell on Windows 10, or use an online Linux Terminal

您会发现当管道 运行ning 时 Docker 机器上可用的 sed command cannot handle regexes with positive lookahead or negative lookahead, so we have to use perl instead. We also need to simulate the BITBUCKET_BUILD_NUMBER 环境变量。

# Simulate the Bitbucket Pipelines build number in our local Terminal
export BITBUCKET_BUILD_NUMBER=123

# Create a JSON text file to test with
# 

cat > package.json <<EOF
{
  "name": "myApp",
  "version": "22.01.36"
}
EOF

# Copy the file to a backup
cp package.json copy-package.json

# Run the regex using Perl with inline replace. Use a fixed string "123" for the build number
# 
perl -pi -e 's/("version".*:.*"\d.*(?="))/b123/g' package.json

# Restore from the backup and test again
cp copy-package.json package.json

# Run the regex using Perl with inline replace. Use an environment variable for the build number
# https://unix.stackexchange.com/questions/581295/using-bash-variable-in-perl-command-in-bash
perl -pi -e 's/("version".*:.*"\d.*(?="))/b$ENV{BITBUCKET_BUILD_NUMBER}/g' package.json

# Verify the file is changed correctly
cat package.json

{
  "name": "myApp",
  "version": "22.01.36b123"
}

3。将 Bash 命令添加到 YML 脚本

pipelines:
  branches:
    master:
      - step:
          ...
          script:
            - npm install
            - npm install -g @angular/cli
            - npm run build-stage --progress=false

            # Get the path of the first 'package.json' which is closest to the root folder
            # 
            - JSON_FILE_PATH=$(find "$(pwd -P)" -name package.json | awk '{ print length, [=11=] }' | sort -n -s | cut -d" " -f2- | head -1)
            - echo "BITBUCKET_BUILD_NUMBER = $BITBUCKET_BUILD_NUMBER"
            - echo "JSON_FILE_PATH = $JSON_FILE_PATH"

            # Debug: Print the original package.json
            - cat "$JSON_FILE_PATH"

            # Delete any existing 'bNNN' in the version string of package.json
            - perl -pi -e 's/b\d*"/"/g' "$JSON_FILE_PATH"

            # Modify the package.json to insert the $BITBUCKET_BUILD_NUMBER into the version string
            - perl -pi -e 's/("version".*:.*"\d.*(?="))/b$ENV{BITBUCKET_BUILD_NUMBER}/g' "$JSON_FILE_PATH"

            # Debug: Print the modified package.json
            - cat "$JSON_FILE_PATH"

            # Possibly needed - Commit the modified package.json to Git
            - git commit -am "Add the BITBUCKET_BUILD_NUMBER into the 'version' in package.json [skip ci]"
            - git push