Search code examples
npmazure-devopsazure-pipelines

ADO Pipeline publish npm package to local Artifacts


I've been struggling with getting my npm package to publish correctly to my local ADO Artifact repository using ADO pipelines and a YAML file. Everything was looking good, until I attempted to use the package in another project, and discovered that only the package.json file was published along with the node_modules folder, not the code that was generated by npm build.

Also, that the code that is being generated for the package is from a subset of the total Storybook project. It's just some theming code as of right now, with the rest of the components being handled later.

Here is my YAML file:

trigger:
  branches:
    include:
      - master
  paths:
    include:
      - src/themes
  tags:
    include:
      - patch
    exclude:
      - major
      - minor

resources:
  - repo: self

stages:
  - stage: Publish
    displayName: Publish Theme Package
    jobs:
      - job: Publish
        displayName: Publish to ADO Artifact feed
        pool:
          vmImage: "ubuntu-latest"
        steps:
          - checkout: self
            persistCredentials: true
            clean: true
          - task: npmAuthenticate@0
            inputs:
              workingFile: .npmrc
          - task: NodeTool@0
            displayName: "update node.js to latest version"
            inputs:
              versionSource: "spec"
              versionSpec: "20.x"
              checkLatest: true
          - task: Npm@1
            displayName: "Update npm to latest version"
            inputs:
              command: "custom"
              customCommand: "install -g npm@latest"
          - task: Npm@1
            displayName: npm install
            inputs:
              command: install
          - task: Npm@1
            displayName: npm run build
            inputs:
              command: "custom"
              customCommand: "run build"

          # - task: CopyFiles@2
          #   inputs:
          #     SourceFolder: '/src/themes'
          #     Contents: |
          #       /src/themes/*
          #     TargetFolder: '/src/dist'
          #   displayName: 'Copy theme files'
          
          # - task: PublishPipelineArtifact@1
          #   inputs:
          #     targetPath: '$(Build.ArtifactsStagingDirectory)'
          #     artifact: 'wec-themes'
          #     publishLocation: 'pipeline'
          #   displayName: 'Publish npm artifact'
    
          - bash: | # Grab the package version
               v=`node -p "const p = require('./package.json'); p.version;"`
               echo "##vso[task.setvariable variable=packageVersion]$v"
          - task: CmdLine@2 # Push changes to GitHub (substitute your repo)   
            inputs:
              script: |
                git config --global user.email "[email protected]"
                git config --global user.name "Azure Pipeline"
                git add package.json
                git commit -a -m "Automated Commit from Azure DevOps"
                git push -u origin HEAD:master
          - task: Npm@1
            displayName: npm version patch
            inputs:
              command: "custom"
              customCommand: "version patch -force"
          - task: Npm@1
            displayName: npm publish
            inputs:
              command: publish
              publishRegistry: useFeed
              publishFeed: removed
              workingDir: "/dist/"
              verbose: true


I've commented out some of the copy commands, only because I was trying to get it to work.

NPM Build logs from the latest run:

cropped the first 30 lines
> [email protected] build
> tsc && vite build

vite v5.2.12 building for production...
transforming...
✓ 284 modules transformed.
rendering chunks...

[vite:dts] Start generate declaration files...
computing gzip size...
dist/base-theme.js            0.08 kB │ gzip:  0.09 kB
dist/index.js                 0.23 kB │ gzip:  0.14 kB
dist/light/light-theme.js     5.71 kB │ gzip:  1.43 kB
dist/dark/dark-theme.js       8.31 kB │ gzip:  1.57 kB
dist/base-theme-DYM8UH8-.js  95.62 kB │ gzip: 23.51 kB
[vite:dts] Declaration files built in 4305ms.

✓ built in 5.57s

Finishing: npm run build

{
  "name": "design-portal",
  "private": true,
  "version": "1.1.2",
  "type": "module",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build",
    "prepublishOnly": "npm run build"
  },
  "dependencies": {
 ...

I still receiving an error on publish. See the log below

Starting: npm publish
==============================================================================
Task         : npm
Description  : Install and publish npm packages, or run an npm command. Supports npmjs.com and authenticated registries like Azure Artifacts.
Version      : 1.242.1
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/package/npm
==============================================================================
##[warning]Can't find loc string for key: Info_GotAndMaskAuth
##[warning]Can't find loc string for key: Info_GotAndMaskAuth
/opt/hostedtoolcache/node/20.15.1/x64/bin/npm --version
10.8.2
##[warning]Can't find loc string for key: Info_GotAndMaskAuth
##[warning]Can't find loc string for key: Info_GotAndMaskAuth
##[warning]Can't find loc string for key: Info_GotAndMaskAuth
##[warning]Can't find loc string for key: Info_GotAndMaskAuth
##[error]Error: ENOENT: no such file or directory, stat '/dist/*'
Finishing: npm publish

Adding additional details around the @latest

npm publish task error


Solution

  • I have checked the Pipeline log and confirmed that the files are existing in the dist folder.

    To include the dist folder in the npm package, you can add the files filed in the package.json file and set the dist folder.

    For example:

    Package.json

    {
      "name": "angular-realworld",
      "version": "0.0.0",  
       .....
      "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
    
      },
      "engines": {
        "node": "^18.13.0 || ^20.9.0"
      },
      "files": [
        "dist/",
        "src/"
      ],
     
      "dependencies": {
    ...
    }
    

    Note: We need to set the dist folder path based on the actual path.

    Refer to the doc: files in package.json

    The "files" field is an array of files to include in your project. If you name a folder in the array, then it will also include the files inside that folder. (Unless they would be ignored by another rule.)

    On the other hand, you can check if the .gitignore or .npmignore files are existing in your repo. If yes, you can check if the dist folder has been excluded in the ignore file.

    When you npm publish, if you don't have an .npmignore file, npm will use your .gitignore file.

    You can create a .npmignore file based on your .gitignore file, without ignoring the dist folder. Refer to this doc: Keeping files out of your Package

    Here is my result:

    enter image description here

    Update:

    ##[error]Error: ENOENT: no such file or directory, stat '/dist/*'

    For the latest error in the question, the cause of the issue is that you need to define the package.json file folder path in the npm task instead of the dist folder.

    For example:

          - task: Npm@1
            displayName: npm publish
            inputs:
              command: publish
              publishRegistry: useFeed
              publishFeed: removed
              workingDir: "folder path where package.json located"
              verbose: true