0
votes

I'm doing a proof-of-concept for my organization using Azure DevOps Pipelines to handle our front-end CI builds.

I've created two Angular projects: a library project and an application project that consumes that library. I've each to its own DevOps Project within my Organization, each of which has its own Repo. (e.g., the library Angular code is in My-Org/My-Library's Project's Repo, and the application that consumes that library is in My-Org/My-Application's Project's Repo.)

I've successfully gotten DevOps to publish that library's package to its Artifacts. I've successfully installed that package from Artifacts for my application from the CLI using npm install.

When I try to build the same application using an Azure Pipeline, things start out looking good but then I get warnings:

...
2020-09-25T01:40:22.9633584Z npm verb npm-session b9c6c5c07bc27d0f
2020-09-25T01:40:22.9634637Z npm info lifecycle @<myorganization>/<my-application-package-name>@0.0.0~preinstall: @<myorganization>/<my-application-package-name>@0.0.0
...
2020-09-25T01:40:22.9652940Z npm http fetch GET 200 https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz 888ms
2020-09-25T01:40:22.9653589Z npm http fetch GET 200 https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz 885ms
...
2020-09-25T01:40:22.9696448Z npm http fetch GET 200 https://registry.npmjs.org/tar/-/tar-6.0.5.tgz 256ms
2020-09-25T01:40:22.9697172Z npm WARN tar ENOENT: no such file or directory, open '/home/vsts/work/1/s/node_modules/.staging/source-map-655ef13e/dist/source-map.js'
2020-09-25T01:40:22.9697948Z npm http fetch GET 200 https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz 254ms
2020-09-25T01:40:22.9698728Z npm WARN tar ENOENT: no such file or directory, open '/home/vsts/work/1/s/node_modules/.staging/@angular/cli-095a8231/commands/build-impl.js'
2020-09-25T01:40:22.9699541Z npm WARN tar ENOENT: no such file or directory, open '/home/vsts/work/1/s/node_modules/.staging/engine.io-client-a00fe2c5/LICENSE'
...

culminating with the unhappy finale:

...
2020-09-25T01:40:23.9366311Z npm WARN tar ENOENT: no such file or directory, open '/home/vsts/work/1/s/node_modules/.staging/rxjs-77a83855/LICENSE.txt'
2020-09-25T01:40:23.9367111Z npm WARN tar ENOENT: no such file or directory, open '/home/vsts/work/1/s/node_modules/.staging/rxjs-77a83855/src/LICENSE.txt'
2020-09-25T01:40:23.9367879Z npm verb unlock done using /home/vsts/.npm/_locks/staging-b6ade8de5fa1f467.lock for /home/vsts/work/1/s/node_modules/.staging
2020-09-25T01:40:23.9369511Z npm verb stack Error: 404 Not Found - GET https://pkgs.dev.azure.com/<MyOrganization>/<My-Library-Project>/_packaging/<My-Library-Project-Artifact-Feed>/npm/registry/@<myorganization>/<my-library-package-name>/-/<my-library-package-name>-0.0.6.tgz
...
2020-09-25T01:40:23.9371625Z npm verb statusCode 404
2020-09-25T01:40:23.9372024Z npm verb pkgid @<myorganization>/<my-library-package-name>@0.0.6
2020-09-25T01:40:23.9372260Z npm verb cwd /home/vsts/work/1/s
2020-09-25T01:40:23.9372620Z npm verb Linux 5.4.0-1025-azure
2020-09-25T01:40:23.9373034Z npm verb argv "/opt/hostedtoolcache/node/12.18.4/x64/bin/node" "/opt/hostedtoolcache/node/12.18.4/x64/bin/npm" "install"
2020-09-25T01:40:23.9373392Z npm verb node v12.18.4
2020-09-25T01:40:23.9373573Z npm verb npm  v6.14.6
2020-09-25T01:40:23.9373749Z npm ERR! code E404
2020-09-25T01:40:23.9374536Z npm ERR! 404 Not Found - GET https://pkgs.dev.azure.com/<MyOrganization>/<My-Library-Project>/_packaging/<My-Library-Project-Artifact-Feed>/npm/registry/@<myorganization>/<my-library-package-name>/-/<my-library-package-name>-0.0.6.tgz
2020-09-25T01:40:23.9375074Z npm ERR! 404
2020-09-25T01:40:23.9375516Z npm ERR! 404  '@<myorganization>/<my-library-package-name>@0.0.6' is not in the npm registry.
...

But here's the weird part: if I click on that url in the browser for which the Pipeline is reporting a 404---https://pkgs.dev.azure.com/<MyOrganization>/<My-Library-Project>/_packaging/<My-Library-Project-Artifact-Feed>/npm/registry/@<myorganization>/<my-library-package-name>/-/<my-library-package-name>-0.0.6.tgz---the browser downloads my package!

So to summarize:

  1. When doing an npm install from the command-line for my application project, I'm able to install the package from the library's DevOps Artifacts, and
  2. When clicking on the very URL that the application Pipeline log says is failing, the browser downloads the package from the library's Artifacts, but
  3. The application's Pipeline that runs inside my DevOps Organization can't find it.

I suspect some kind of permissions or authorization issue, but I'm not sure where to go from here.

I've tried the npmAuthenticate@0 task, and indeed the logs say encouraging things like:

2020-09-25T01:40:04.2511306Z ##[debug]Got auth token
..
2020-09-25T01:40:04.2540281Z ##[debug]Created webApi client for https://dev.azure.com/<MyOrganization>/; options: {"proxy":null,"allowRetries":true,"maxRetries":5,"ignoreSslError":false}
2020-09-25T01:40:04.2581233Z ##[debug]Getting URI for area ID <some GUID> from https://dev.azure.com/<MyOrganization>/
2020-09-25T01:40:04.3973124Z ##[debug]Found resource area with locationUrl: https://pkgs.dev.azure.com/<MyOrganization>/
2020-09-25T01:40:04.3976465Z ##[debug]Found serviceUri: https://pkgs.dev.azure.com/<MyOrganization>/
2020-09-25T01:40:04.3978178Z ##[debug]Getting credentials for local feeds
2020-09-25T01:40:04.3978962Z SYSTEMVSSCONNECTION exists true
2020-09-25T01:40:04.3979926Z ##[debug]SYSTEMVSSCONNECTION exists true
2020-09-25T01:40:04.4003325Z ##[debug]Got auth token
2020-09-25T01:40:04.4004250Z ##[debug]Agent.ProxyUrl=undefined
2020-09-25T01:40:04.4005572Z ##[debug]Created webApi client for https://pkgs.dev.azure.com/<MyOrganization>/; options: {"proxy":null,"allowRetries":true,"maxRetries":5,"ignoreSslError":false}
2020-09-25T01:40:04.4007252Z ##[debug]Acquiring Packaging endpoints...
2020-09-25T01:40:04.6490830Z ##[debug]Successfully acquired the connection data
2020-09-25T01:40:04.6502681Z ##[debug]Acquired location
2020-09-25T01:40:04.6503915Z ##[debug]{"PackagingUris":["https://dev.azure.com/<MyOrganization>/","https://pkgs.dev.azure.com/<MyOrganization>/","https://pkgsprodcus1.pkgs.visualstudio.com/","https://pkgs.dev.azure.com/<MyOrganization>/","https://<myorganization>.pkgs.visualstudio.com/","https://pkgs.dev.azure.com/<MyOrganization>/"],"DefaultPackagingUri":"https://pkgs.dev.azure.com/<MyOrganization>/"}

Yet it still fails.

Any suggestions on what I can try?

Thanks!!

P.S. I should add that I have a lot more information I can share including my package.json, .npmrc, and the entire log but I wanted to keep this brief. If you need me to share additional details, please let me know and I'll add them. Thank you!

1

1 Answers

1
votes

When connecting to a private project scoped feed from an Azure DevOps pipeline that is in the same organization but in a different project, the project that the feed is scoped to must allow access to the other project's build service. The build service must also be separately added to the feed permissions, regardless of the scope of the feed.

This is a problem with project scoped feed permissions. In short, to access a project scoped feed that is scoped to a project that is different than the project that the pipeline is running in, the project that the pipeline is running in must have access to BOTH the project that the feed is scoped to and the feed itself.

Here's how to set the proper permissions.

  1. Check the project that the pipeline is running in. The build service permission that needs to be added to the feed permission and the feed's project permissions is going to look like something like [Project name] Build Service ([Organization name]).

  2. In the project that the feed is scoped to, go to the permission settings to add the pipeline's project build service ([Project name] Build Service ([Organization name])) to a the Contributors group, or some other group your project may have that allows contributor access to its users.

  3. In the feed permission page, add the [Project name] Build Service ([Organization name]) at least Collaborator access, so packages can be ingested from upstream sources. If you only give read permissions, packages cannot be ingested from upstream sources.