Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .azure-pipelines/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ name: $(Date:yyyyMMdd).$(Rev:r)
variables:
- name: Codeql.Enabled
value: true
- name: npm_config_userconfig
value: $(Agent.TempDirectory)/.npmrc
- template: /.azure-pipelines/npm-cfs-variables.yml@self
resources:
repositories:
- repository: self
Expand Down
3 changes: 1 addition & 2 deletions .azure-pipelines/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ name: $(Date:yyyyMMdd).$(Rev:r)
variables:
- name: Codeql.Enabled
value: true
- name: npm_config_userconfig
value: $(Agent.TempDirectory)/.npmrc
- template: /.azure-pipelines/npm-cfs-variables.yml@self
schedules:
- cron: 0 0 * * *
branches:
Expand Down
28 changes: 28 additions & 0 deletions .azure-pipelines/npm-cfs-variables.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Variables required to route npm package restore through the Central Feed Service
# (CFS). Consumed by every pipeline in this directory alongside the npm-cfs.yml steps
# template, which is where these values are actually applied.
#
# Both are declared here rather than in each pipeline so the feed URL exists in
# exactly one place.
#
# npm_config_registry is not redundant with the registry written into the generated
# .npmrc. npm resolves configuration in the order cli > environment > project .npmrc
# > user .npmrc, so a registry supplied only through the user config is outranked by
# anything the agent image already configures -- Microsoft hosted images ship a user
# level .npmrc pointing at an internal proxy, and a pool that exports
# npm_config_registry would win outright. Restore would then quietly resolve from
# somewhere other than CFS while the build still reported success. Declaring the
# variable here puts the redirect at environment precedence, where only an explicit
# command line flag can override it.
#
# npm matches npm_config_* environment variables case insensitively, so the
# uppercased form that Azure Pipelines exports applies to every step on every OS.
# That matters because package restore here is not driven by a single task: `npm
# install`, `npx json`, `npx @vscode/vsce` and the vsce invocation inside AzureCLI@2
# all inherit the agent environment rather than reading a task input.

variables:
- name: npm_config_registry
value: https://pkgs.dev.azure.com/mseng/VSJava/_packaging/vscjava/npm/registry/
- name: npm_config_userconfig
value: $(Agent.TempDirectory)/.npmrc
42 changes: 28 additions & 14 deletions .azure-pipelines/npm-cfs.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Single source of truth for routing npm package restore through the Central Feed
# Service (CFS), as required by SFI Network Isolation. Every build pipeline in this
# directory consumes this template, so the feed URL is declared exactly once.
# Routes npm package restore through the Central Feed Service (CFS), as required by
# SFI Network Isolation. Consumed by every build pipeline in this directory.
#
# Pipelines must also include the companion variables template:
# variables:
# - template: /.azure-pipelines/npm-cfs-variables.yml@self
# which declares the feed URL and the generated .npmrc path. The redirect itself is
# carried by the npm_config_registry environment variable that template exports; see
# its header for why the generated .npmrc alone is not enough.
#
# The .npmrc is generated at build time into the agent temp directory rather than
# being committed to the repository, so that:
Expand All @@ -11,10 +17,9 @@
# * the configuration does not depend on the repository being checked out, so
# release jobs consuming a prebuilt artifact work the same way as build jobs.
#
# Pipelines consuming this template must also declare the pipeline level variable
# npm_config_userconfig: $(Agent.TempDirectory)/.npmrc
# npm matches npm_config_* environment variables case insensitively, so the
# uppercased form that Azure Pipelines exports applies to every step on every OS.
# The registry is still written into that file because NpmAuthenticate discovers the
# registries to authenticate by reading it. npm then takes the URL from the
# environment and the matching credential from this file.
#
# The file is written with `npm config set` rather than a shell redirect because the
# pipelines span both Windows (VSEng-MicroBuildVSStable) and Linux
Expand All @@ -26,14 +31,14 @@
# This template must run after the Node install task, and before any step that
# restores packages -- including `npx`, which resolves downloads through the
# configured registry.

parameters:
- name: npmrcPath
type: string
default: $(Agent.TempDirectory)/.npmrc
#
# Consumers must reference this file as `/.azure-pipelines/npm-cfs.yml@self`. A
# relative path is resolved against the file doing the including, which for these
# pipelines is the 1ES extends template in another repository, so the unqualified
# form is looked up in 1ESPipelineTemplates and fails YAML compilation.

steps:
- script: npm config set registry https://pkgs.dev.azure.com/mseng/VSJava/_packaging/vscjava/npm/registry/ --location=user --userconfig="${{ parameters.npmrcPath }}"
- script: npm config set registry $(npm_config_registry) --location=user --userconfig="$(npm_config_userconfig)"
displayName: Configure CFS npm registry

# Appends `//pkgs.dev.azure.com/.../registry/:_authToken=<token>` for every registry
Expand All @@ -42,4 +47,13 @@ steps:
- task: NpmAuthenticate@0
displayName: Authenticate to CFS feed
inputs:
workingFile: ${{ parameters.npmrcPath }}
workingFile: $(npm_config_userconfig)

# Restore silently falling back to the public registry is the failure mode this
# whole template exists to prevent, and it leaves no trace in the build log, so it
# is asserted rather than assumed. Written in node, which the preceding Node
# install task guarantees, to avoid shell differences between the Linux and
# Windows pools.
- script: >-
node -e "const cp=require('child_process');const r=cp.execSync('npm config get registry').toString().trim();console.log('npm registry -> '+r);if(!r.startsWith('https://pkgs.dev.azure.com/')){console.error('##vso[task.logissue type=error]npm is not configured against the CFS feed');process.exit(1);}"
displayName: Verify CFS npm registry
3 changes: 1 addition & 2 deletions .azure-pipelines/rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ name: $(Date:yyyyMMdd).$(Rev:r)
variables:
- name: Codeql.Enabled
value: true
- name: npm_config_userconfig
value: $(Agent.TempDirectory)/.npmrc
- template: /.azure-pipelines/npm-cfs-variables.yml@self
resources:
repositories:
- repository: self
Expand Down
3 changes: 1 addition & 2 deletions .azure-pipelines/release-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ name: $(Date:yyyyMMdd).$(Rev:r) # Use the current date and a revision number for
variables:
- name: Codeql.Enabled
value: true
- name: npm_config_userconfig
value: $(Agent.TempDirectory)/.npmrc
- template: /.azure-pipelines/npm-cfs-variables.yml@self
resources:
repositories:
- repository: self
Expand Down
3 changes: 1 addition & 2 deletions .azure-pipelines/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ name: $(Date:yyyyMMdd).$(Rev:r) # Use the current date and a revision number for
variables:
- name: Codeql.Enabled
value: true
- name: npm_config_userconfig
value: $(Agent.TempDirectory)/.npmrc
- template: /.azure-pipelines/npm-cfs-variables.yml@self
resources:
repositories:
- repository: self
Expand Down
Loading