-
Notifications
You must be signed in to change notification settings - Fork 123
Expand file tree
/
Copy pathsetup.yml
More file actions
154 lines (137 loc) · 6.27 KB
/
Copy pathsetup.yml
File metadata and controls
154 lines (137 loc) · 6.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# DevDiv pipeline setup steps
#
# Notes on custom registry support:
# - Custom npm registry setup is implemented inline below (no external scripts).
# - The template creates a temp .npmrc, sets NPM_CONFIG_USERCONFIG/REGISTRY, and
# rewrites lockfiles via a transient JS helper emitted into Agent.TempDirectory.
parameters:
- name: installNode
type: boolean
default: true
- name: installPython
type: boolean
default: true
- name: customNPMRegistry
type: string
default: ''
- name: nodeVersion
type: string
default: '22.17.0'
- name: pythonVersion
type: string
default: '3.9'
- name: npmrcPath
type: string
default: '$(Agent.TempDirectory)/.npmrc'
steps:
- ${{ if eq(parameters.installNode, true) }}:
- task: NodeTool@0
inputs:
versionSpec: ${{ parameters.nodeVersion }}
checkLatest: true
displayName: 🛠 Install Node ${{ parameters.nodeVersion }}
- ${{ if ne(parameters.customNPMRegistry, '') }}:
# When using a private/custom registry, configure npm to read auth/config from a temp user config
# instead of relying on a checked-in project .npmrc.
- pwsh: |
$path = "${{ parameters.npmrcPath }}"
if (Test-Path -LiteralPath $path -PathType Container) {
throw "npmrcPath points to a directory (expected a file): $path"
}
$parent = Split-Path -Parent $path
if ($parent -and -not (Test-Path -LiteralPath $parent)) {
New-Item -ItemType Directory -Path $parent -Force | Out-Null
}
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
New-Item -ItemType File -Path $path -Force | Out-Null
}
Write-Host "##vso[task.setvariable variable=NPM_CONFIG_USERCONFIG]$path"
Write-Host "##vso[task.setvariable variable=NPM_CONFIG_REGISTRY]${{ parameters.customNPMRegistry }}"
displayName: 📦 Setup NPM User Config
# Configure npm/yarn to use the custom registry and ensure auth headers are sent.
- pwsh: |
$path = "${{ parameters.npmrcPath }}"
$registry = "${{ parameters.customNPMRegistry }}"
$env:NPM_CONFIG_USERCONFIG = $path
$env:NPM_CONFIG_REGISTRY = $registry
npm config set registry "$registry"
# npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb
# following is a workaround for yarn-like clients to send authorization header for GET
# requests to the registry.
"always-auth=true" | Out-File -FilePath $path -Append -Encoding utf8
$yarn = Get-Command yarn -ErrorAction SilentlyContinue
if ($null -ne $yarn) {
yarn config set registry "$registry"
} else {
Write-Host "yarn not found; skipping yarn registry configuration"
}
displayName: 📦 Setup NPM & Yarn
# Populate the temp .npmrc with auth for the configured registry.
- task: npmAuthenticate@0
inputs:
workingFile: ${{ parameters.npmrcPath }}
displayName: 📦 Setup NPM Authentication
# Some lockfiles contain hardcoded references to public registries. Rewrite them so installs
# and `npx` resolve from the custom registry consistently.
- pwsh: |
$registry = "${{ parameters.customNPMRegistry }}"
$env:NPM_CONFIG_REGISTRY = $registry
$scriptPath = Join-Path "$(Agent.TempDirectory)" 'setup-npm-registry.js'
$lines = @(
"const fs = require('fs').promises;",
"const path = require('path');",
"",
"async function* getLockFiles(dir) {",
" const files = await fs.readdir(dir);",
"",
" for (const file of files) {",
" const fullPath = path.join(dir, file);",
" const stat = await fs.stat(fullPath);",
"",
" if (stat.isDirectory()) {",
" if (file === 'node_modules' || file === '.git') {",
" continue;",
" }",
" yield* getLockFiles(fullPath);",
" } else if (file === 'yarn.lock' || file === 'package-lock.json') {",
" yield fullPath;",
" }",
" }",
"}",
"",
"async function rewrite(file, registry) {",
" let contents = await fs.readFile(file, 'utf8');",
" const re = new RegExp('https://registry\\.[^.]+\\.(com|org)/', 'g');",
" contents = contents.replace(re, registry);",
" await fs.writeFile(file, contents);",
"}",
"",
"async function main() {",
" const root = process.cwd();",
" const registry = process.env.NPM_CONFIG_REGISTRY;",
" if (!registry) { throw new Error('NPM_CONFIG_REGISTRY is not set'); }",
"",
" for await (const file of getLockFiles(root)) {",
" await rewrite(file, registry);",
" console.log('Updated node registry:', file);",
" }",
"}",
"",
"main();"
)
Set-Content -LiteralPath $scriptPath -Value ($lines -join "`n") -Encoding utf8
node $scriptPath
displayName: 📦 Setup NPM Registry
- script: npm config get registry
displayName: Verify NPM Registry
- ${{ if eq(parameters.installPython, true) }}:
- task: PipAuthenticate@1
displayName: 'Pip Authenticate'
inputs:
artifactFeeds: 'DevDiv/debugpy'
- task: UsePythonVersion@0
inputs:
versionSpec: ${{ parameters.pythonVersion }}
addToPath: true
architecture: 'x64'
displayName: Select Python ${{ parameters.pythonVersion }}