生成、测试和部署 JavaScript Node.js应用

Azure Pipelines | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018 | TFS 2017

可以使用一个Azure DevOps来生成和测试 JavaScript Node.js应用,然后部署或发布到目标。

注意

以下指南适用于 Team Foundation Server (2017.3) 及更高版本的 TFS。

先决条件

必须具有以下项:Azure DevOps:

创建管道

  1. 将以下存储库分叉到GitHub。
https://github.com/Azure-Samples/js-e2e-express-server

  1. 登录到 Azure Pipelines。 浏览器转到 仪表板 https://dev.azure.com/my-organization-name 并显示Azure DevOps仪表板。

  2. 转到项目并选择"Pipelines管道"。

  3. 选择GitHub作为源代码的位置。

  4. 如果重定向到登录GitHub,请输入GitHub凭据。

  5. 当存储库列表出现时,请选择Node.js存储库。

  6. Azure Pipelines分析存储库中的代码,并推荐 Node.js 管道的模板。 选择该模板。

  7. Azure Pipelines为管道生成 YAML 文件。 选择"保存"并直接运行"提交到主分支",然后选择"保存并再次运行"。

  8. 新的运行将启动。 等待运行完成。

完成后,存储库中有一个 () YAML 文件可供 azure-pipelines.yml 自定义。

若要更改 YAML 文件,请选择管道,然后选择" 编辑文件 "。

创建管道

YAML

  1. 将以下存储库分叉到GitHub。

    https://github.com/Azure-Samples/js-e2e-express-server
    
  2. azure-pipelines.yml 存储库中添加文件。 此 YAML 假设已在服务器上Node.js npm。

trigger:
- main

pool: Default

- script: |
    npm install
    npm run build
  displayName: 'npm install and build'
  1. 创建管道并选择YAML 模板。

  2. 设置 管道的代理和 YAML 文件路径。

  3. 保存管道并排入生成队列。 当" 生成#nnnnnnnn.n 已排队"消息出现时,请选择数字链接以查看管道的运行状态。

  4. 你随时都可以编辑管道。

经典

  1. 将以下存储库分叉到GitHub。

    https://github.com/Azure-Samples/js-e2e-express-server
    
  2. 在你自己的存储库中拥有示例代码后,创建第一个 管道并选择 " 空进程" 模板。

  3. 管道编辑器 的" 任务" 选项卡下选择"处理",并按如下所示更改属性:

    • 代理队列:
  4. 按指定顺序将以下任务添加到管道:

    • npm

      • 命令:
    • npm

      • 显示名称:
      • 命令:
      • 命令和参数:
    • 发布测试结果

      • 保留属性的所有默认值
    • 存档文件

      • 要存档的根文件夹或文件:
      • 在存档路径中预先预置根文件夹名称: 未选中
    • 发布生成工件

      • 保留属性的所有默认值
  5. 保存管道并排入生成队列,以查看其运行。

请进一步阅读,了解自定义 JavaScript 生成过程的一些更常用方法。

设置生成环境

可以使用 Azure Pipelines生成 JavaScript 应用,而无需设置自己的任何基础结构。 可以使用 Windows Linux 代理来运行生成。

在文件中更新以下 azure-pipelines.yml 代码片段,以选择相应的映像。

pool:
  vmImage: 'ubuntu-latest' # examples of other options: 'macOS-10.15', 'windows-latest'

通常用于生成、测试和运行 JavaScript 应用的工具(例如 npm、Node、Yarn 和 Gulp)预安装在 Azure Pipelines 中的Microsoft托管代理上。 有关预Node.js和 npm 的版本,请参阅 Microsoft 托管代理。 若要在 Microsoft 托管的代理上安装这些工具的特定版本,将 Node Tool Installer 任务添加到进程的开头。

也可使用自 承载代理

使用特定版本的Node.js

如果需要 Microsoft 托管的代理Node.js和 npm 版本,请使用 Node 工具安装程序任务。 将以下代码片段添加到 azure-pipelines.yml 文件。

注意

托管代理会定期更新,设置此任务会导致每次运行管道时花费大量时间更新到较新的次要版本。 仅在管道中需要特定 Node 版本时,才使用此任务。

- task: NodeTool@0 
  inputs:
    versionSpec: '12.x' # replace this value with the version that you need for your project

如果需要代理上尚未Node.js/npm 的版本:

  1. 在管道中,选择"任务",选择运行生成任务的阶段,然后选择将 新任务添加到该阶段。

  2. 在任务目录中,找到并添加 "节点工具安装程序" 任务。

  3. 选择任务并指定要Node.js运行时的版本。

若要仅更新 npm 工具,请运行 npm i -g npm@version-number 生成过程中的命令。

使用多个节点版本

可以使用 Node 工具安装程序任务 在多个版本的 Node 上生成 和测试应用

pool:
  vmImage: 'ubuntu-latest'
strategy:
  matrix:
    node_12_x:
      node_version: 12.x
    node_13_x:
      node_version: 13.x

steps:
- task: NodeTool@0 
  inputs:
    versionSpec: $(node_version)

- script: npm install

请参阅 多配置执行

在生成代理中安装工具

如果项目或文件中具有开发依赖项 package.jsonpackage-lock.json 的工具,请通过 npm 安装工具和依赖项。 工具的确切版本在项目中定义,与生成代理上存在的其他版本隔离。

使用 脚本npm 任务

使用脚本通过 package.json 进行安装

- script: npm install --only=dev

使用 npm 任务通过 package.json 进行安装

- task: Npm@1
  inputs:
     command: 'install'

使用 npm 包运行程序运行此方式安装的工具,该运行程序在其路径解析中检测以此方式 npx 安装的工具。 以下示例调用测试运行程序,但先查找作为开发依赖项安装的版本,然后再使用全局安装 (到) mochanpm install -g 版本。

- script: npx mocha

若要安装项目需要但不在 中设置为开发依赖项的工具,请从管道中的 package.jsonnpm install -g 脚本阶段调用 。

以下示例使用 安装最新版本的Angular CLI。 然后,管道的其余部分可以从其他 ng 阶段使用 script 该工具。

注意

在 Microsoft 托管的 Linux 代理上,在 命令的前跟 sudo ,例如 sudo npm install -g

- script: npm install -g @angular/cli

提示

这些任务每次运行管道时都会运行,因此请注意安装工具对生成时间的影响。 如果开销 对生成性能 造成严重影响,请考虑使用所需的工具版本配置自承载代理。

使用管道中的 npm或命令行任务在生成代理上安装工具。

管理依赖项

在生成中,使用Yarn或 Azure Artifacts从公共应用程序下载npm 注册表。 此注册表是在 .npmrc npm 注册表中指定的一种专用注册表。

使用 npm

可以通过以下方式使用 npm 下载生成包:

  • 直接 npm install 在管道中运行,这是无需身份验证即可从注册表下载包的最简单方法。 如果生成不需要代理上的开发依赖项来运行,可以使用 选项来加快 --only=prod 生成时间 npm install
  • 使用 npm 任务。 使用经过身份验证的注册表时,此任务非常有用。
  • 使用 npm 身份验证任务。 从任务运行程序 npm install (Gulp、Grunt 或 Maven)内部运行时,此任务非常有用。

如果要指定一个npm 注册表,请将 URL 放在存储库中 .npmrc 的文件中。 如果源已经过身份验证,请通过设置中的"服务"选项卡Project npm服务连接,以管理其凭据。

若要在管道中安装包含脚本的 npm 包,请向 添加以下代码片段 azure-pipelines.yml

- script: npm install

若要使用文件中指定的专用注册表 .npmrc ,请向 添加以下代码片段 azure-pipelines.yml

- task: Npm@1
  inputs:
    customEndpoint: <Name of npm service connection>

若要通过任务运行程序(如 Gulp)将注册表凭据传递给 npm 命令,在调用任务运行程序之前,将以下 azure-pipelines.yml 任务添加到 。

- task: npmAuthenticate@0
  inputs:
    customEndpoint: <Name of npm service connection>

使用 管道中的 npmnpm 身份验证 任务下载并安装包。

如果在从数据库还原包时,由于连接问题,生成偶尔会失败npm 注册表,可以将Azure Artifacts上游源一起使用,并缓存包。 连接到管道时,会自动使用管道的Azure Artifacts。 这些凭据通常派生自 Project生成服务帐户。

如果使用 Microsoft托管代理,则每次运行生成时都会获得一台新计算机,这意味着每次还原依赖项,这可能需要很长时间。 若要缓解问题,Azure Artifacts或自承载代理 - 然后就可以使用包缓存。

使用 Yarn

使用脚本阶段调用 Yarn 来还原依赖项。 Yarn 预装在某些 Microsoft 托管代理 上。 可以像任何其他工具一样在自承载代理上安装和配置它。

- script: yarn install

使用 管道中的 CLIBash 任务调用 Yarn

运行 JavaScript 编译器

使用CompilerlTypeScript编译器将源代码转换为运行时或 web 浏览器中Node.js 的版本。

如果在运行 编译器的项目 文件中设置了脚本对象,则使用脚本任务在管道 中调用它。

- script: npm run compile

可以使用脚本任务直接从管道调用编译器。 这些命令从克隆的源代码存储库的根目录运行。

- script: tsc --target ES6 --strict true --project tsconfigs/production.json

如果在项目 package.json 中定义了编译脚本来生成代码,请使用管道中的 npm 任务。 如果未 在项目 配置中定义单独的脚本,请使用 Bash 任务编译代码。

运行单元测试

配置管道以运行 JavaScript 测试,以便生成 JUnit XML 格式的结果。 然后,可以使用内置的发布测试结果 任务发布 结果。

如果测试框架不支持 JUnit 输出,请通过合作伙伴报告模块(如 mocha-junit-reporter)添加支持。 可以更新测试脚本以使用 JUnit 记者,或者,如果报员支持命令行选项,可以将这些选项传递到任务定义中。

下表列出了最常用的测试运行程序以及可用于生成 XML 结果的报告者:

测试运行程序 生成 XML 报表的记者
摩 卡 mocha-junit-reporter
cypress-multi-reporters
茉莉花 jasmine-reporters
开玩笑 jest-junit
jest-junit-reporter
karma-junit-reporter
Ava tap-xunit

以下示例使用 mocha-junit-reporter, 并使用 脚本直接调用 。 此脚本在 的默认位置生成 JUnit XML 输出 ./test-results.xml

- script: mocha test --reporter mocha-junit-reporter

如果在项目 test package.json 文件中定义了脚本,可以使用 调用它 npm test

- script: npm test

发布测试结果

若要发布结果, 请使用"发布 测试结果任务。

- task: PublishTestResults@2
  condition: succeededOrFailed()
  inputs:
    testRunner: JUnit
    testResultsFiles: '**/test-results.xml'

发布代码覆盖率结果

如果测试脚本运行代码覆盖率工具(如 "处理者"),请添加"发布 代码覆盖率结果" 任务。 这样做时,可以在生成摘要中查找覆盖率指标,并下载 HTML 报表进行进一步分析。 该任务需要 Cobertura 或 JaCoCo 报告输出,因此请确保代码覆盖率工具使用生成正确输出所需的选项运行。 例如,--report cobertura

以下示例使用 nyc,即处理命令行接口,以及 mocha-junit-reporter 并调用 命令。

- script: |
    nyc --reporter=cobertura --reporter=html \
    npm test -- --reporter mocha-junit-reporter --reporter-options mochaFile=./test-results.xml
  displayName: 'Build code coverage report'

- task: PublishCodeCoverageResults@1
  inputs: 
    codeCoverageTool: Cobertura # or JaCoCo
    summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/*coverage.xml'
    reportDirectory: '$(System.DefaultWorkingDirectory)/**/coverage'

使用管道测试结果发布代码覆盖率结果"任务,使用"代码覆盖率结果"发布测试结果和代码覆盖率结果。

为"发布任务"任务测试结果"控制选项",即使上一个任务失败,也运行该任务,除非已取消部署。

端到端测试浏览器

在无头浏览器中运行测试,作为管道的一部分,使用工具(如用户或Karma)。 然后,使用以下步骤将生成Azure DevOps发布结果:

  1. 在生成代理上安装无头浏览器测试驱动程序(如无头 Chrome 或 Firefox)或浏览器模拟工具(如虚拟JS)。
  2. 根据工具的文档,将测试框架配置为使用你选择的无头浏览器/驱动程序选项。
  3. 配置测试框架 (通常使用报告器插件或) 输出 JUnit 格式的测试结果。
  4. 设置脚本任务以运行启动无头浏览器实例所需的任何 CLI 命令。
  5. 在管道阶段运行端到端测试以及单元测试。
  6. 将同一个"发布测试结果 任务与 单元测试一起发布结果。

打包 Web 应用

打包应用程序,以将中间输出和依赖项的所有应用程序模块捆绑到可供部署的静态资产中。 在编译和测试后添加管道阶段,以使用 Angular CLI 运行webpackng build 等工具。

第一个示例调用 webpack 。 若要完成此操作,请确保在 package.json 项目文件中将 配置为开发 webpack 依赖项。 除非项目的根文件夹中有文件,否则此操作会使用默认 webpackwebpack.config.js 配置运行。

- script: webpack

下一个示例使用 npm 任务调用 来 调用在 build 项目 package.json 中定义的脚本对象。 在项目中使用脚本对象会将生成的逻辑移动到源代码和管道外。

- script: npm run build

使用管道中的CLIBash任务调用打包工具,例如 Angular

实现 JavaScript 框架

Angular

对于Angular,可以包含特定于Angular命令,例如ng test、ngbuildng e2e。 若要在Angular CLI 命令,请安装生成代理上的angular/cli npm包。

注意

在 Microsoft 托管的 Linux 代理上,在 命令的前跟 sudo ,例如 sudo npm install -g

- script: |
    npm install -g @angular/cli
    npm install
    ng build --prod

将以下任务添加到管道:

  • npm

    • 命令:
    • 命令和参数:
  • npm

    • 命令:
  • bash

    • 类型:
    • 脚本:

对于管道中需要运行浏览器的测试,例如运行 Karma 的初学者应用中的 ng test 命令,请使用无头浏览器而不是标准浏览器。 在 Angular入门应用中:

  1. browsers 项目karma.conf.js中的browsers条目从 browsers: ['Chrome'] 更改为 browsers: ['ChromeHeadless']

  2. singleRun 项目karma.conf.js中的singleRun条目从 值更改为 falsetrue 。 此更改可帮助确保 Karma 进程在运行后停止。

React和 Vue

package.json文件中React和 Vue 应用的所有依赖项。 azure-pipelines.yml文件包含标准Node.js脚本:

- script: |
    npm install
    npm run build
 displayName: 'npm install and build'

生成文件在一个新文件夹中, (dist Vue) 或 build (React) 。 此代码片段生成一个 www 可供发布的项目 。 它使用节点安装程序、复制文件和发布生成Artifacts任务。

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: NodeTool@0
  inputs:
    versionSpec: '10.x'
  displayName: 'Install Node.js'

- script: |
    npm install
    npm run build
  displayName: 'npm install and build'

- task: CopyFiles@2
  inputs:
    Contents: 'build/**' # Pull the build directory (React)
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: PublishBuildArtifacts@1
  inputs: 
    PathtoPublish: $(Build.ArtifactStagingDirectory) # dist or build files
    ArtifactName: 'www' # output artifact named www

若要发布,将发布任务指向 distbuild 项目,并使用 dist

Webpack

可以使用 webpack 配置文件来指定编译器(如用户或 TypeScript)将 JSX 或 TypeScript 转译为普通 JavaScript,以及捆绑应用。

- script: |
    npm install webpack webpack-cli --save-dev
    npx webpack --config webpack.config.js

将以下任务添加到管道:

  • npm

    • 命令:
    • 命令和参数:
  • bash

    • 类型:
    • 脚本:

生成任务运行程序

通常使用 GulpGrunt 作为任务运行程序来生成和测试 JavaScript 应用。

Gulp

Gulp 预装在 Microsoft 托管代理上。 在 gulp YAML 文件中运行 命令:

- script: gulp                       # include any additional options that are needed

如果配置文件中的gulpfile.js要求使用证书进行身份验证npm 注册表:

- task: npmAuthenticate@0
  inputs:
    customEndpoint: <Name of npm service connection>

- script: gulp                       # include any additional options that are needed

添加" 发布测试结果 任务,将 JUnit 或 xUnit 测试结果发布到服务器。

- task: PublishTestResults@2
  inputs:
    testResultsFiles: '**/TEST-RESULTS.xml'
    testRunTitle: 'Test results for JavaScript using gulp'

添加" 发布代码覆盖率结果" 任务,将代码覆盖率结果发布到服务器。 可以在生成摘要中查找覆盖率指标,并可以下载 HTML 报表进行进一步分析。

- task: PublishCodeCoverageResults@1
  inputs: 
    codeCoverageTool: Cobertura
    summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/*coverage.xml'
    reportDirectory: '$(System.DefaultWorkingDirectory)/**/coverage'

如果应用使用 Gulp,则创建管道的最简单Node.js是在创建管道时将Node.js生成模板与 gulp 生成模板一起使用。 此模板会自动添加各种任务来调用 Gulp 命令和发布项目。 在任务中,选择 "启用代码覆盖率 ",以使用"土耳其"启用代码覆盖率。

Grunt

Grunt 预装在 Microsoft 托管代理上。 在 YAML 文件中运行 grunt 命令:

- script: grunt                      # include any additional options that are needed

如果文件中的步骤 Gruntfile.js 需要使用以下方法进行身份验证npm 注册表:

- task: npmAuthenticate@0
  inputs:
    customEndpoint: <Name of npm service connection>

- script: grunt                      # include any additional options that are needed

如果应用使用 Grunt,则创建管道的最简单Node.js是在创建管道时将配置与 Grunt 生成模板一起使用。 这会自动添加各种任务来调用 Gulp 命令和发布项目。 在任务中,选择"发布到 TFS/Team Services"选项以发布测试结果,然后选择"启用代码覆盖率"以使用"启用代码覆盖率"。

打包并交付代码

生成并测试应用后,可以将生成输出上传到 Azure Pipelines,创建并发布 npm 或 Maven 包,或将生成输出打包到 .zip 文件中,以部署到 Web 应用程序。

将文件发布到Azure Pipelines

若要上传文件的整个工作目录,请使用发布生成Artifacts任务,将以下内容添加到 文件。

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)'

若要上传文件的子集,请首先使用"复制文件"任务将所需文件从工作目录复制到暂存目录,然后使用"发布生成Artifacts任务

- task: CopyFiles@2
  inputs:
    SourceFolder: '$(System.DefaultWorkingDirectory)'
    Contents: |
      **\*.js
      package.json
    TargetFolder: '$(Build.ArtifactStagingDirectory)'

- task: PublishBuildArtifacts@1

将模块发布到npm 注册表

如果项目的输出是供其他项目而不是 Web 应用程序使用的模块,请使用 npm 任务将模块发布到本地注册表 npm 或公共npm 注册表。 npm 每次发布时提供唯一的名称/版本组合。

示例

第一个示例假定你管理版本信息 (例如通过 npm 版本) 通过版本控制中的文件 更改进行管理。 以下示例使用脚本任务发布到公共注册表。

- script: npm publish

下一个示例将发布到存储库文件中定义的自定义 .npmrc 注册表。 设置 npm 服务连接, 以在生成运行时将身份验证凭据注入连接。

- task: Npm@1
  inputs:
     command: publish
     publishRegistry: useExternalRegistry
     publishEndpoint: https://my.npmregistry.com

最后一个示例将模块发布到Azure DevOps Services源。

- task: Npm@1
  inputs:
     command: publish
     publishRegistry: useFeed
     publishFeed: https://my.npmregistry.com

有关版本控制及发布 npm 包的信息,请参阅发布npm包和如何在生成过程中对 npm 包进行版本控制?。

部署 Web 应用

若要创建.zip Web 应用的存档文件存档,请使用存档 文件 任务:

- task: ArchiveFiles@2
  inputs:
    rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
    includeRootFolder: false

若要将此存档发布到 Web 应用,请参阅 Azure Web 应用部署

将项目发布到Azure Pipelines

使用"发布生成Artifacts任务将文件从生成发布到Azure Pipelines。

发布到npm 注册表

若要创建和发布 npm 包,请使用 npm 任务。 有关版本控制及发布 npm 包的信息,请参阅 发布 npm 包

部署 Web 应用

若要创建.zip Web 应用的存档文件存档,请使用存档 文件任务。 若要将此存档发布到 Web 应用,请参阅 Azure Web 应用部署

生成映像并推送到容器注册表

成功生成源代码并完成单元测试后,还可以生成映像,并推送到容器注册表

疑难解答

如果可以在开发计算机上生成项目,但在生成项目时遇到Azure Pipelines,请探索以下潜在原因和纠正措施:

  • 检查开发 计算机上Node.js运行 程序的版本是否与代理上的版本匹配。 可以在管道中包括命令行脚本(例如 ) node --version 来检查代理上安装的 。 使用节点 工具 安装程序 (如本指南) 在代理上部署相同版本,或运行命令将工具更新为 所需的版本。

  • 如果在还原包时生成间歇性失败,则npm 注册表出现问题,或者 Azure 数据中心与注册表之间存在网络问题。 我们无法控制这些因素。 了解是否Azure Artifacts将 npm 注册表用作上游源可提高生成的可靠性。

  • 如果使用 来管理不同版本的应用程序 nvm ,Node.js切换到 nvm 任务。 (nvm macOS 映像上出于历史原因安装 ) nvm通过Node.js shell 别名和更改 管理多个版本,这与新进程中Azure Pipelines运行每个任务 PATHnvm

    节点 工具安装程序 任务正确处理此模型。 但是,如果你的工作需要使用 ,可以将以下 nvm 脚本添加到每个管道的开头:

    steps:
    - bash: |
        NODE_VERSION=12  # or whatever your preferred version is
        npm config delete prefix  # avoid a warning
        . ${NVM_DIR}/nvm.sh
        nvm use ${NODE_VERSION}
        nvm alias default ${NODE_VERSION}
        VERSION_PATH="$(nvm_version_path ${NODE_VERSION})"
        echo "##vso[task.prependPath]$VERSION_PATH"
    

    然后 node ,和其他命令行工具适用于管道作业的其余部分。 在命令的每个步骤 nvm 中,使用以下代码启动脚本:

    - bash: |
        . ${NVM_DIR}/nvm.sh
        nvm <command>
    

常见问题解答

问:在哪里可以了解有关Azure Artifacts和包管理服务?

:包管理Azure Artifacts

问:在哪里可以详细了解任务?

:生成、发布和测试任务

问:如何实现修复管道故障,并出现消息"错误:CALL_AND_RETRY_LAST分配失败 - JavaScript 堆内存不足"?

答:此失败类型在Node.js超出内存使用限制时发生。 若要解决此问题,请添加等变量,并为其分配值 NODE_OPTIONSNODE_OPTIONS

问:如何在生成过程中对 npm 包进行版本控制?

答:一个选项是结合使用版本控制和 npm 版本。 管道运行结束时,可以使用新版本更新存储库。 在此 YAML 中,有一GitHub存储库,包部署到 npmjs。 如果 npmjs 上的包版本与文件不匹配,生成 package.json 将失败。

variables:
    MAP_NPMTOKEN: $(NPMTOKEN) # Mapping secret var

trigger:
- none

pool:
  vmImage: 'ubuntu-latest'

steps: # Checking out connected repo
- checkout: self
  persistCredentials: true
  clean: true
    
- task: npmAuthenticate@0
  inputs:
    workingFile: .npmrc
    customEndpoint: 'my-npm-connection'
    
- task: NodeTool@0
  inputs:
    versionSpec: '12.x'
  displayName: 'Install Node.js'

- script: |
    npm install
  displayName: 'npm install'

- script: |
    npm pack
  displayName: 'Package for release'

- bash: | # Grab the package version
    v=`node -p "const p = require('./package.json'); p.version;"`
    echo "##vso[task.setvariable variable=packageVersion]$v"

- task: CopyFiles@2
  inputs:
      contents: '*.tgz'
      targetFolder: $(Build.ArtifactStagingDirectory)/npm
  displayName: 'Copy archives to artifacts staging directory'

- task: CopyFiles@2
  inputs:
    sourceFolder: '$(Build.SourcesDirectory)'
    contents: 'package.json' 
    targetFolder: $(Build.ArtifactStagingDirectory)/npm
  displayName: 'Copy package.json'

- task: PublishBuildArtifacts@1 
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)/npm'
    artifactName: npm
  displayName: 'Publish npm artifact'

- script: |  # Config can be set in .npmrc
    npm config set //registry.npmjs.org/:_authToken=$(MAP_NPMTOKEN) 
    npm config set scope "@myscope"
    # npm config list
    # npm --version
    npm version patch --force
    npm publish --access public

- task: CmdLine@2 # Push changes to GitHub (substitute your repo)
  inputs:
    script: |
      git config --global user.email "username@contoso.com"
      git config --global user.name "Azure Pipeline"
      git add package.json
      git commit -a -m "Test Commit from Azure DevOps"
      git push -u origin HEAD:main