mirror of
				https://github.com/actions/setup-node.git
				synced 2025-10-31 16:23:34 +00:00 
			
		
		
		
	Add support for volta.extends (#921)
				
					
				
			* Add support for `volta.extends` * Code review
This commit is contained in:
		
							parent
							
								
									b39b52d121
								
							
						
					
					
						commit
						d86ebcd40b
					
				
							
								
								
									
										20
									
								
								.github/workflows/versions.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.github/workflows/versions.yml
									
									
									
									
										vendored
									
									
								
							| @ -162,9 +162,6 @@ jobs: | |||||||
|           [.nvmrc, .tool-versions, .tool-versions-node, package.json] |           [.nvmrc, .tool-versions, .tool-versions-node, package.json] | ||||||
|     steps: |     steps: | ||||||
|       - uses: actions/checkout@v4 |       - uses: actions/checkout@v4 | ||||||
|       - name: Remove volta from package.json |  | ||||||
|         shell: bash |  | ||||||
|         run: cat <<< "$(jq 'del(.volta)' ./__tests__/data/package.json)" > ./__tests__/data/package.json |  | ||||||
|       - name: Setup node from node version file |       - name: Setup node from node version file | ||||||
|         uses: ./ |         uses: ./ | ||||||
|         with: |         with: | ||||||
| @ -183,7 +180,22 @@ jobs: | |||||||
|       - name: Setup node from node version file |       - name: Setup node from node version file | ||||||
|         uses: ./ |         uses: ./ | ||||||
|         with: |         with: | ||||||
|           node-version-file: '__tests__/data/package.json' |           node-version-file: '__tests__/data/package-volta.json' | ||||||
|  |       - name: Verify node | ||||||
|  |         run: __tests__/verify-node.sh 16 | ||||||
|  | 
 | ||||||
|  |   version-file-volta-extends: | ||||||
|  |     runs-on: ${{ matrix.os }} | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         os: [ubuntu-latest, windows-latest, macos-latest] | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v4 | ||||||
|  |       - name: Setup node from node version file | ||||||
|  |         uses: ./ | ||||||
|  |         with: | ||||||
|  |           node-version-file: '__tests__/data/package-volta-extends.json' | ||||||
|       - name: Verify node |       - name: Verify node | ||||||
|         run: __tests__/verify-node.sh 16 |         run: __tests__/verify-node.sh 16 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								__tests__/data/package-volta-extends.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								__tests__/data/package-volta-extends.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | { | ||||||
|  |   "volta": { | ||||||
|  |     "extends": "./package-volta.json" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								__tests__/data/package-volta.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								__tests__/data/package-volta.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | { | ||||||
|  |   "engines": { | ||||||
|  |     "node": "^14.0.0" | ||||||
|  |   }, | ||||||
|  |   "volta": { | ||||||
|  |     "node": "16.0.0" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -1,8 +1,5 @@ | |||||||
| { | { | ||||||
|   "engines": { |   "engines": { | ||||||
|     "node": "^14.0.0" |     "node": "^14.0.0" | ||||||
|   }, |  | ||||||
|   "volta": { |  | ||||||
|     "node": "16.0.0" |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -24,11 +24,9 @@ describe('main tests', () => { | |||||||
|   let startGroupSpy: jest.SpyInstance; |   let startGroupSpy: jest.SpyInstance; | ||||||
|   let endGroupSpy: jest.SpyInstance; |   let endGroupSpy: jest.SpyInstance; | ||||||
| 
 | 
 | ||||||
|   let existsSpy: jest.SpyInstance; |  | ||||||
| 
 |  | ||||||
|   let getExecOutputSpy: jest.SpyInstance; |   let getExecOutputSpy: jest.SpyInstance; | ||||||
| 
 | 
 | ||||||
|   let parseNodeVersionSpy: jest.SpyInstance; |   let getNodeVersionFromFileSpy: jest.SpyInstance; | ||||||
|   let cnSpy: jest.SpyInstance; |   let cnSpy: jest.SpyInstance; | ||||||
|   let findSpy: jest.SpyInstance; |   let findSpy: jest.SpyInstance; | ||||||
|   let isCacheActionAvailable: jest.SpyInstance; |   let isCacheActionAvailable: jest.SpyInstance; | ||||||
| @ -41,6 +39,7 @@ describe('main tests', () => { | |||||||
|     // node
 |     // node
 | ||||||
|     os = {}; |     os = {}; | ||||||
|     console.log('::stop-commands::stoptoken'); |     console.log('::stop-commands::stoptoken'); | ||||||
|  |     process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data'); | ||||||
|     process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 |     process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | ||||||
|     process.env['GITHUB_OUTPUT'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 |     process.env['GITHUB_OUTPUT'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
 | ||||||
|     infoSpy = jest.spyOn(core, 'info'); |     infoSpy = jest.spyOn(core, 'info'); | ||||||
| @ -62,12 +61,10 @@ describe('main tests', () => { | |||||||
| 
 | 
 | ||||||
|     isCacheActionAvailable = jest.spyOn(cache, 'isFeatureAvailable'); |     isCacheActionAvailable = jest.spyOn(cache, 'isFeatureAvailable'); | ||||||
| 
 | 
 | ||||||
|     existsSpy = jest.spyOn(fs, 'existsSync'); |  | ||||||
| 
 |  | ||||||
|     cnSpy = jest.spyOn(process.stdout, 'write'); |     cnSpy = jest.spyOn(process.stdout, 'write'); | ||||||
|     cnSpy.mockImplementation(line => { |     cnSpy.mockImplementation(line => { | ||||||
|       // uncomment to debug
 |       // uncomment to debug
 | ||||||
|       // process.stderr.write('write:' + line + '\n');
 |       process.stderr.write('write:' + line + '\n'); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     setupNodeJsSpy = jest.spyOn(OfficialBuilds.prototype, 'setupNodeJs'); |     setupNodeJsSpy = jest.spyOn(OfficialBuilds.prototype, 'setupNodeJs'); | ||||||
| @ -85,7 +82,7 @@ describe('main tests', () => { | |||||||
|     jest.restoreAllMocks(); |     jest.restoreAllMocks(); | ||||||
|   }, 100000); |   }, 100000); | ||||||
| 
 | 
 | ||||||
|   describe('parseNodeVersionFile', () => { |   describe('getNodeVersionFromFile', () => { | ||||||
|     each` |     each` | ||||||
|       contents                                     | expected |       contents                                     | expected | ||||||
|       ${'12'}                                      | ${'12'} |       ${'12'}                                      | ${'12'} | ||||||
| @ -100,10 +97,27 @@ describe('main tests', () => { | |||||||
|       ${'unknown format'}                          | ${'unknown format'} |       ${'unknown format'}                          | ${'unknown format'} | ||||||
|       ${'  14.1.0  '}                              | ${'14.1.0'} |       ${'  14.1.0  '}                              | ${'14.1.0'} | ||||||
|       ${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'}| ${'>=14.0.0 <=17.0.0'} |       ${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'}| ${'>=14.0.0 <=17.0.0'} | ||||||
|  |       ${'{"volta": {"extends": "./package.json"}}'}| ${'18.0.0'} | ||||||
|       ${'{"engines": {"node": "17.0.0"}}'}         | ${'17.0.0'} |       ${'{"engines": {"node": "17.0.0"}}'}         | ${'17.0.0'} | ||||||
|       ${'{}'}                                      | ${null} |       ${'{}'}                                      | ${null} | ||||||
|     `.it('parses "$contents"', ({contents, expected}) => {
 |     `.it('parses "$contents"', ({contents, expected}) => {
 | ||||||
|       expect(util.parseNodeVersionFile(contents)).toBe(expected); |       const existsSpy = jest.spyOn(fs, 'existsSync'); | ||||||
|  |       existsSpy.mockImplementation(() => true); | ||||||
|  | 
 | ||||||
|  |       const readFileSpy = jest.spyOn(fs, 'readFileSync'); | ||||||
|  |       readFileSpy.mockImplementation(filePath => { | ||||||
|  |         if ( | ||||||
|  |           typeof filePath === 'string' && | ||||||
|  |           path.basename(filePath) === 'package.json' | ||||||
|  |         ) { | ||||||
|  |           // Special case for volta.extends
 | ||||||
|  |           return '{"volta": {"node": "18.0.0"}}'; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return contents; | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect(util.getNodeVersionFromFile('file')).toBe(expected); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
| @ -142,10 +156,17 @@ describe('main tests', () => { | |||||||
| 
 | 
 | ||||||
|   describe('node-version-file flag', () => { |   describe('node-version-file flag', () => { | ||||||
|     beforeEach(() => { |     beforeEach(() => { | ||||||
|       parseNodeVersionSpy = jest.spyOn(util, 'parseNodeVersionFile'); |       delete inputs['node-version']; | ||||||
|  |       inputs['node-version-file'] = '.nvmrc'; | ||||||
|  | 
 | ||||||
|  |       getNodeVersionFromFileSpy = jest.spyOn(util, 'getNodeVersionFromFile'); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('not used if node-version is provided', async () => { |     afterEach(() => { | ||||||
|  |       getNodeVersionFromFileSpy.mockRestore(); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('does not read node-version-file if node-version is provided', async () => { | ||||||
|       // Arrange
 |       // Arrange
 | ||||||
|       inputs['node-version'] = '12'; |       inputs['node-version'] = '12'; | ||||||
| 
 | 
 | ||||||
| @ -153,107 +174,54 @@ describe('main tests', () => { | |||||||
|       await main.run(); |       await main.run(); | ||||||
| 
 | 
 | ||||||
|       // Assert
 |       // Assert
 | ||||||
|       expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0); |       expect(inputs['node-version']).toBeDefined(); | ||||||
|     }, 10000); |       expect(inputs['node-version-file']).toBeDefined(); | ||||||
| 
 |       expect(getNodeVersionFromFileSpy).not.toHaveBeenCalled(); | ||||||
|     it('not used if node-version-file not provided', async () => { |  | ||||||
|       // Act
 |  | ||||||
|       await main.run(); |  | ||||||
| 
 |  | ||||||
|       // Assert
 |  | ||||||
|       expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0); |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     it('reads node-version-file if provided', async () => { |  | ||||||
|       // Arrange
 |  | ||||||
|       const versionSpec = 'v14'; |  | ||||||
|       const versionFile = '.nvmrc'; |  | ||||||
|       const expectedVersionSpec = '14'; |  | ||||||
|       process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data'); |  | ||||||
|       inputs['node-version-file'] = versionFile; |  | ||||||
| 
 |  | ||||||
|       parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec); |  | ||||||
|       existsSpy.mockImplementationOnce( |  | ||||||
|         input => input === path.join(__dirname, 'data', versionFile) |  | ||||||
|       ); |  | ||||||
| 
 |  | ||||||
|       // Act
 |  | ||||||
|       await main.run(); |  | ||||||
| 
 |  | ||||||
|       // Assert
 |  | ||||||
|       expect(existsSpy).toHaveBeenCalledTimes(1); |  | ||||||
|       expect(existsSpy).toHaveReturnedWith(true); |  | ||||||
|       expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec); |  | ||||||
|       expect(infoSpy).toHaveBeenCalledWith( |  | ||||||
|         `Resolved ${versionFile} as ${expectedVersionSpec}` |  | ||||||
|       ); |  | ||||||
|     }, 10000); |  | ||||||
| 
 |  | ||||||
|     it('reads package.json as node-version-file if provided', async () => { |  | ||||||
|       // Arrange
 |  | ||||||
|       const versionSpec = fs.readFileSync( |  | ||||||
|         path.join(__dirname, 'data/package.json'), |  | ||||||
|         'utf-8' |  | ||||||
|       ); |  | ||||||
|       const versionFile = 'package.json'; |  | ||||||
|       const expectedVersionSpec = '14'; |  | ||||||
|       process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data'); |  | ||||||
|       inputs['node-version-file'] = versionFile; |  | ||||||
| 
 |  | ||||||
|       parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec); |  | ||||||
|       existsSpy.mockImplementationOnce( |  | ||||||
|         input => input === path.join(__dirname, 'data', versionFile) |  | ||||||
|       ); |  | ||||||
|       // Act
 |  | ||||||
|       await main.run(); |  | ||||||
| 
 |  | ||||||
|       // Assert
 |  | ||||||
|       expect(existsSpy).toHaveBeenCalledTimes(1); |  | ||||||
|       expect(existsSpy).toHaveReturnedWith(true); |  | ||||||
|       expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec); |  | ||||||
|       expect(infoSpy).toHaveBeenCalledWith( |  | ||||||
|         `Resolved ${versionFile} as ${expectedVersionSpec}` |  | ||||||
|       ); |  | ||||||
|     }, 10000); |  | ||||||
| 
 |  | ||||||
|     it('both node-version-file and node-version are provided', async () => { |  | ||||||
|       inputs['node-version'] = '12'; |  | ||||||
|       const versionSpec = 'v14'; |  | ||||||
|       const versionFile = '.nvmrc'; |  | ||||||
|       const expectedVersionSpec = '14'; |  | ||||||
|       process.env['GITHUB_WORKSPACE'] = path.join(__dirname, '..'); |  | ||||||
|       inputs['node-version-file'] = versionFile; |  | ||||||
| 
 |  | ||||||
|       parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec); |  | ||||||
| 
 |  | ||||||
|       // Act
 |  | ||||||
|       await main.run(); |  | ||||||
| 
 |  | ||||||
|       // Assert
 |  | ||||||
|       expect(existsSpy).toHaveBeenCalledTimes(0); |  | ||||||
|       expect(parseNodeVersionSpy).not.toHaveBeenCalled(); |  | ||||||
|       expect(warningSpy).toHaveBeenCalledWith( |       expect(warningSpy).toHaveBeenCalledWith( | ||||||
|         'Both node-version and node-version-file inputs are specified, only node-version will be used' |         'Both node-version and node-version-file inputs are specified, only node-version will be used' | ||||||
|       ); |       ); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it('should throw an error if node-version-file is not found', async () => { |     it('does not read node-version-file if node-version-file is not provided', async () => { | ||||||
|       const versionFile = '.nvmrc'; |       // Arrange
 | ||||||
|       const versionFilePath = path.join(__dirname, '..', versionFile); |       delete inputs['node-version-file']; | ||||||
|       inputs['node-version-file'] = versionFile; |  | ||||||
| 
 | 
 | ||||||
|       inSpy.mockImplementation(name => inputs[name]); |       // Act
 | ||||||
|       existsSpy.mockImplementationOnce( |       await main.run(); | ||||||
|         input => input === path.join(__dirname, 'data', versionFile) | 
 | ||||||
|  |       // Assert
 | ||||||
|  |       expect(getNodeVersionFromFileSpy).not.toHaveBeenCalled(); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('reads node-version-file', async () => { | ||||||
|  |       // Arrange
 | ||||||
|  |       const expectedVersionSpec = '14'; | ||||||
|  |       getNodeVersionFromFileSpy.mockImplementation(() => expectedVersionSpec); | ||||||
|  | 
 | ||||||
|  |       // Act
 | ||||||
|  |       await main.run(); | ||||||
|  | 
 | ||||||
|  |       // Assert
 | ||||||
|  |       expect(getNodeVersionFromFileSpy).toHaveBeenCalled(); | ||||||
|  |       expect(infoSpy).toHaveBeenCalledWith( | ||||||
|  |         `Resolved ${inputs['node-version-file']} as ${expectedVersionSpec}` | ||||||
|  |       ); | ||||||
|  |     }, 10000); | ||||||
|  | 
 | ||||||
|  |     it('should throw an error if node-version-file is not accessible', async () => { | ||||||
|  |       // Arrange
 | ||||||
|  |       inputs['node-version-file'] = 'non-existing-file'; | ||||||
|  |       const versionFilePath = path.join( | ||||||
|  |         __dirname, | ||||||
|  |         'data', | ||||||
|  |         inputs['node-version-file'] | ||||||
|       ); |       ); | ||||||
| 
 | 
 | ||||||
|       // Act
 |       // Act
 | ||||||
|       await main.run(); |       await main.run(); | ||||||
| 
 | 
 | ||||||
|       // Assert
 |       // Assert
 | ||||||
|       expect(existsSpy).toHaveBeenCalled(); |       expect(getNodeVersionFromFileSpy).toHaveBeenCalled(); | ||||||
|       expect(existsSpy).toHaveReturnedWith(false); |  | ||||||
|       expect(parseNodeVersionSpy).not.toHaveBeenCalled(); |  | ||||||
|       expect(cnSpy).toHaveBeenCalledWith( |       expect(cnSpy).toHaveBeenCalledWith( | ||||||
|         `::error::The specified node version file at: ${versionFilePath} does not exist${osm.EOL}` |         `::error::The specified node version file at: ${versionFilePath} does not exist${osm.EOL}` | ||||||
|       ); |       ); | ||||||
|  | |||||||
							
								
								
									
										61
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								dist/cache-save/index.js
									
									
									
									
										vendored
									
									
								
							| @ -83329,49 +83329,60 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | |||||||
|         step((generator = generator.apply(thisArg, _arguments || [])).next()); |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  | var __importDefault = (this && this.__importDefault) || function (mod) { | ||||||
|  |     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||||
|  | }; | ||||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||||
| exports.unique = exports.printEnvDetailsAndSetOutput = exports.parseNodeVersionFile = void 0; | exports.unique = exports.printEnvDetailsAndSetOutput = exports.getNodeVersionFromFile = void 0; | ||||||
| const core = __importStar(__nccwpck_require__(2186)); | const core = __importStar(__nccwpck_require__(2186)); | ||||||
| const exec = __importStar(__nccwpck_require__(1514)); | const exec = __importStar(__nccwpck_require__(1514)); | ||||||
| function parseNodeVersionFile(contents) { | const fs_1 = __importDefault(__nccwpck_require__(7147)); | ||||||
|     var _a, _b, _c; | const path_1 = __importDefault(__nccwpck_require__(1017)); | ||||||
|     let nodeVersion; | function getNodeVersionFromFile(versionFilePath) { | ||||||
|  |     var _a, _b, _c, _d, _e; | ||||||
|  |     if (!fs_1.default.existsSync(versionFilePath)) { | ||||||
|  |         throw new Error(`The specified node version file at: ${versionFilePath} does not exist`); | ||||||
|  |     } | ||||||
|  |     const contents = fs_1.default.readFileSync(versionFilePath, 'utf8'); | ||||||
|     // Try parsing the file as an NPM `package.json` file.
 |     // Try parsing the file as an NPM `package.json` file.
 | ||||||
|     try { |     try { | ||||||
|         const manifest = JSON.parse(contents); |         const manifest = JSON.parse(contents); | ||||||
|         // JSON can parse numbers, but that's handled later
 |         // Presume package.json file.
 | ||||||
|         if (typeof manifest === 'object') { |         if (typeof manifest === 'object' && !!manifest) { | ||||||
|             nodeVersion = (_a = manifest.volta) === null || _a === void 0 ? void 0 : _a.node; |             // Support Volta.
 | ||||||
|             if (!nodeVersion) |             // See https://docs.volta.sh/guide/understanding#managing-your-project
 | ||||||
|                 nodeVersion = (_b = manifest.engines) === null || _b === void 0 ? void 0 : _b.node; |             if ((_a = manifest.volta) === null || _a === void 0 ? void 0 : _a.node) { | ||||||
|             // if contents are an object, we parsed JSON
 |                 return manifest.volta.node; | ||||||
|  |             } | ||||||
|  |             if ((_b = manifest.engines) === null || _b === void 0 ? void 0 : _b.node) { | ||||||
|  |                 return manifest.engines.node; | ||||||
|  |             } | ||||||
|  |             // Support Volta workspaces.
 | ||||||
|  |             // See https://docs.volta.sh/advanced/workspaces
 | ||||||
|  |             if ((_c = manifest.volta) === null || _c === void 0 ? void 0 : _c.extends) { | ||||||
|  |                 const extendedFilePath = path_1.default.resolve(path_1.default.dirname(versionFilePath), manifest.volta.extends); | ||||||
|  |                 core.info('Resolving node version from ' + extendedFilePath); | ||||||
|  |                 return getNodeVersionFromFile(extendedFilePath); | ||||||
|  |             } | ||||||
|  |             // If contents are an object, we parsed JSON
 | ||||||
|             // this can happen if node-version-file is a package.json
 |             // this can happen if node-version-file is a package.json
 | ||||||
|             // yet contains no volta.node or engines.node
 |             // yet contains no volta.node or engines.node
 | ||||||
|             //
 |             //
 | ||||||
|             // if node-version file is _not_ json, control flow
 |             // If node-version file is _not_ JSON, control flow
 | ||||||
|             // will not have reached these lines.
 |             // will not have reached these lines.
 | ||||||
|             //
 |             //
 | ||||||
|             // And because we've reached here, we know the contents
 |             // And because we've reached here, we know the contents
 | ||||||
|             // *are* JSON, so no further string parsing makes sense.
 |             // *are* JSON, so no further string parsing makes sense.
 | ||||||
|             if (!nodeVersion) { |             return null; | ||||||
|                 return null; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     catch (_d) { |     catch (_f) { | ||||||
|         core.info('Node version file is not JSON file'); |         core.info('Node version file is not JSON file'); | ||||||
|     } |     } | ||||||
|     if (!nodeVersion) { |     const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m); | ||||||
|         const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m); |     return (_e = (_d = found === null || found === void 0 ? void 0 : found.groups) === null || _d === void 0 ? void 0 : _d.version) !== null && _e !== void 0 ? _e : contents.trim(); | ||||||
|         nodeVersion = (_c = found === null || found === void 0 ? void 0 : found.groups) === null || _c === void 0 ? void 0 : _c.version; |  | ||||||
|     } |  | ||||||
|     // In the case of an unknown format,
 |  | ||||||
|     // return as is and evaluate the version separately.
 |  | ||||||
|     if (!nodeVersion) |  | ||||||
|         nodeVersion = contents.trim(); |  | ||||||
|     return nodeVersion; |  | ||||||
| } | } | ||||||
| exports.parseNodeVersionFile = parseNodeVersionFile; | exports.getNodeVersionFromFile = getNodeVersionFromFile; | ||||||
| function printEnvDetailsAndSetOutput() { | function printEnvDetailsAndSetOutput() { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         core.startGroup('Environment details'); |         core.startGroup('Environment details'); | ||||||
|  | |||||||
							
								
								
									
										67
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -93650,7 +93650,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | |||||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||||
| exports.run = void 0; | exports.run = void 0; | ||||||
| const core = __importStar(__nccwpck_require__(2186)); | const core = __importStar(__nccwpck_require__(2186)); | ||||||
| const fs_1 = __importDefault(__nccwpck_require__(7147)); |  | ||||||
| const os_1 = __importDefault(__nccwpck_require__(2037)); | const os_1 = __importDefault(__nccwpck_require__(2037)); | ||||||
| const auth = __importStar(__nccwpck_require__(7573)); | const auth = __importStar(__nccwpck_require__(7573)); | ||||||
| const path = __importStar(__nccwpck_require__(1017)); | const path = __importStar(__nccwpck_require__(1017)); | ||||||
| @ -93725,10 +93724,7 @@ function resolveVersionInput() { | |||||||
|     } |     } | ||||||
|     if (versionFileInput) { |     if (versionFileInput) { | ||||||
|         const versionFilePath = path.join(process.env.GITHUB_WORKSPACE, versionFileInput); |         const versionFilePath = path.join(process.env.GITHUB_WORKSPACE, versionFileInput); | ||||||
|         if (!fs_1.default.existsSync(versionFilePath)) { |         const parsedVersion = (0, util_1.getNodeVersionFromFile)(versionFilePath); | ||||||
|             throw new Error(`The specified node version file at: ${versionFilePath} does not exist`); |  | ||||||
|         } |  | ||||||
|         const parsedVersion = (0, util_1.parseNodeVersionFile)(fs_1.default.readFileSync(versionFilePath, 'utf8')); |  | ||||||
|         if (parsedVersion) { |         if (parsedVersion) { | ||||||
|             version = parsedVersion; |             version = parsedVersion; | ||||||
|         } |         } | ||||||
| @ -93780,49 +93776,60 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge | |||||||
|         step((generator = generator.apply(thisArg, _arguments || [])).next()); |         step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  | var __importDefault = (this && this.__importDefault) || function (mod) { | ||||||
|  |     return (mod && mod.__esModule) ? mod : { "default": mod }; | ||||||
|  | }; | ||||||
| Object.defineProperty(exports, "__esModule", ({ value: true })); | Object.defineProperty(exports, "__esModule", ({ value: true })); | ||||||
| exports.unique = exports.printEnvDetailsAndSetOutput = exports.parseNodeVersionFile = void 0; | exports.unique = exports.printEnvDetailsAndSetOutput = exports.getNodeVersionFromFile = void 0; | ||||||
| const core = __importStar(__nccwpck_require__(2186)); | const core = __importStar(__nccwpck_require__(2186)); | ||||||
| const exec = __importStar(__nccwpck_require__(1514)); | const exec = __importStar(__nccwpck_require__(1514)); | ||||||
| function parseNodeVersionFile(contents) { | const fs_1 = __importDefault(__nccwpck_require__(7147)); | ||||||
|     var _a, _b, _c; | const path_1 = __importDefault(__nccwpck_require__(1017)); | ||||||
|     let nodeVersion; | function getNodeVersionFromFile(versionFilePath) { | ||||||
|  |     var _a, _b, _c, _d, _e; | ||||||
|  |     if (!fs_1.default.existsSync(versionFilePath)) { | ||||||
|  |         throw new Error(`The specified node version file at: ${versionFilePath} does not exist`); | ||||||
|  |     } | ||||||
|  |     const contents = fs_1.default.readFileSync(versionFilePath, 'utf8'); | ||||||
|     // Try parsing the file as an NPM `package.json` file.
 |     // Try parsing the file as an NPM `package.json` file.
 | ||||||
|     try { |     try { | ||||||
|         const manifest = JSON.parse(contents); |         const manifest = JSON.parse(contents); | ||||||
|         // JSON can parse numbers, but that's handled later
 |         // Presume package.json file.
 | ||||||
|         if (typeof manifest === 'object') { |         if (typeof manifest === 'object' && !!manifest) { | ||||||
|             nodeVersion = (_a = manifest.volta) === null || _a === void 0 ? void 0 : _a.node; |             // Support Volta.
 | ||||||
|             if (!nodeVersion) |             // See https://docs.volta.sh/guide/understanding#managing-your-project
 | ||||||
|                 nodeVersion = (_b = manifest.engines) === null || _b === void 0 ? void 0 : _b.node; |             if ((_a = manifest.volta) === null || _a === void 0 ? void 0 : _a.node) { | ||||||
|             // if contents are an object, we parsed JSON
 |                 return manifest.volta.node; | ||||||
|  |             } | ||||||
|  |             if ((_b = manifest.engines) === null || _b === void 0 ? void 0 : _b.node) { | ||||||
|  |                 return manifest.engines.node; | ||||||
|  |             } | ||||||
|  |             // Support Volta workspaces.
 | ||||||
|  |             // See https://docs.volta.sh/advanced/workspaces
 | ||||||
|  |             if ((_c = manifest.volta) === null || _c === void 0 ? void 0 : _c.extends) { | ||||||
|  |                 const extendedFilePath = path_1.default.resolve(path_1.default.dirname(versionFilePath), manifest.volta.extends); | ||||||
|  |                 core.info('Resolving node version from ' + extendedFilePath); | ||||||
|  |                 return getNodeVersionFromFile(extendedFilePath); | ||||||
|  |             } | ||||||
|  |             // If contents are an object, we parsed JSON
 | ||||||
|             // this can happen if node-version-file is a package.json
 |             // this can happen if node-version-file is a package.json
 | ||||||
|             // yet contains no volta.node or engines.node
 |             // yet contains no volta.node or engines.node
 | ||||||
|             //
 |             //
 | ||||||
|             // if node-version file is _not_ json, control flow
 |             // If node-version file is _not_ JSON, control flow
 | ||||||
|             // will not have reached these lines.
 |             // will not have reached these lines.
 | ||||||
|             //
 |             //
 | ||||||
|             // And because we've reached here, we know the contents
 |             // And because we've reached here, we know the contents
 | ||||||
|             // *are* JSON, so no further string parsing makes sense.
 |             // *are* JSON, so no further string parsing makes sense.
 | ||||||
|             if (!nodeVersion) { |             return null; | ||||||
|                 return null; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     catch (_d) { |     catch (_f) { | ||||||
|         core.info('Node version file is not JSON file'); |         core.info('Node version file is not JSON file'); | ||||||
|     } |     } | ||||||
|     if (!nodeVersion) { |     const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m); | ||||||
|         const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m); |     return (_e = (_d = found === null || found === void 0 ? void 0 : found.groups) === null || _d === void 0 ? void 0 : _d.version) !== null && _e !== void 0 ? _e : contents.trim(); | ||||||
|         nodeVersion = (_c = found === null || found === void 0 ? void 0 : found.groups) === null || _c === void 0 ? void 0 : _c.version; |  | ||||||
|     } |  | ||||||
|     // In the case of an unknown format,
 |  | ||||||
|     // return as is and evaluate the version separately.
 |  | ||||||
|     if (!nodeVersion) |  | ||||||
|         nodeVersion = contents.trim(); |  | ||||||
|     return nodeVersion; |  | ||||||
| } | } | ||||||
| exports.parseNodeVersionFile = parseNodeVersionFile; | exports.getNodeVersionFromFile = getNodeVersionFromFile; | ||||||
| function printEnvDetailsAndSetOutput() { | function printEnvDetailsAndSetOutput() { | ||||||
|     return __awaiter(this, void 0, void 0, function* () { |     return __awaiter(this, void 0, void 0, function* () { | ||||||
|         core.startGroup('Environment details'); |         core.startGroup('Environment details'); | ||||||
|  | |||||||
| @ -84,6 +84,8 @@ When using the `package.json` input, the action will look for `volta.node` first | |||||||
| } | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | Otherwise, when [`volta.extends`](https://docs.volta.sh/advanced/workspaces) is defined, then it will resolve the corresponding file and look for `volta.node` or `engines.node` recursively. | ||||||
|  | 
 | ||||||
| ## Architecture | ## Architecture | ||||||
| 
 | 
 | ||||||
| You can use any of the [supported operating systems](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners), and the compatible `architecture` can be selected using `architecture`. Values are `x86`, `x64`, `arm64`, `armv6l`, `armv7l`, `ppc64le`, `s390x` (not all of the architectures are available on all platforms). | You can use any of the [supported operating systems](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners), and the compatible `architecture` can be selected using `architecture`. Values are `x86`, `x64`, `arm64`, `armv6l`, `armv7l`, `ppc64le`, `s390x` (not all of the architectures are available on all platforms). | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/main.ts
									
									
									
									
									
								
							| @ -1,6 +1,5 @@ | |||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
| 
 | 
 | ||||||
| import fs from 'fs'; |  | ||||||
| import os from 'os'; | import os from 'os'; | ||||||
| 
 | 
 | ||||||
| import * as auth from './authutil'; | import * as auth from './authutil'; | ||||||
| @ -8,7 +7,7 @@ import * as path from 'path'; | |||||||
| import {restoreCache} from './cache-restore'; | import {restoreCache} from './cache-restore'; | ||||||
| import {isCacheFeatureAvailable} from './cache-utils'; | import {isCacheFeatureAvailable} from './cache-utils'; | ||||||
| import {getNodejsDistribution} from './distributions/installer-factory'; | import {getNodejsDistribution} from './distributions/installer-factory'; | ||||||
| import {parseNodeVersionFile, printEnvDetailsAndSetOutput} from './util'; | import {getNodeVersionFromFile, printEnvDetailsAndSetOutput} from './util'; | ||||||
| import {State} from './constants'; | import {State} from './constants'; | ||||||
| 
 | 
 | ||||||
| export async function run() { | export async function run() { | ||||||
| @ -99,15 +98,7 @@ function resolveVersionInput(): string { | |||||||
|       versionFileInput |       versionFileInput | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     if (!fs.existsSync(versionFilePath)) { |     const parsedVersion = getNodeVersionFromFile(versionFilePath); | ||||||
|       throw new Error( |  | ||||||
|         `The specified node version file at: ${versionFilePath} does not exist` |  | ||||||
|       ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const parsedVersion = parseNodeVersionFile( |  | ||||||
|       fs.readFileSync(versionFilePath, 'utf8') |  | ||||||
|     ); |  | ||||||
| 
 | 
 | ||||||
|     if (parsedVersion) { |     if (parsedVersion) { | ||||||
|       version = parsedVersion; |       version = parsedVersion; | ||||||
|  | |||||||
							
								
								
									
										59
									
								
								src/util.ts
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/util.ts
									
									
									
									
									
								
							| @ -1,45 +1,62 @@ | |||||||
| import * as core from '@actions/core'; | import * as core from '@actions/core'; | ||||||
| import * as exec from '@actions/exec'; | import * as exec from '@actions/exec'; | ||||||
| 
 | 
 | ||||||
| export function parseNodeVersionFile(contents: string): string | null { | import fs from 'fs'; | ||||||
|   let nodeVersion: string | undefined; | import path from 'path'; | ||||||
|  | 
 | ||||||
|  | export function getNodeVersionFromFile(versionFilePath: string): string | null { | ||||||
|  |   if (!fs.existsSync(versionFilePath)) { | ||||||
|  |     throw new Error( | ||||||
|  |       `The specified node version file at: ${versionFilePath} does not exist` | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   const contents = fs.readFileSync(versionFilePath, 'utf8'); | ||||||
| 
 | 
 | ||||||
|   // Try parsing the file as an NPM `package.json` file.
 |   // Try parsing the file as an NPM `package.json` file.
 | ||||||
|   try { |   try { | ||||||
|     const manifest = JSON.parse(contents); |     const manifest = JSON.parse(contents); | ||||||
| 
 | 
 | ||||||
|     // JSON can parse numbers, but that's handled later
 |     // Presume package.json file.
 | ||||||
|     if (typeof manifest === 'object') { |     if (typeof manifest === 'object' && !!manifest) { | ||||||
|       nodeVersion = manifest.volta?.node; |       // Support Volta.
 | ||||||
|       if (!nodeVersion) nodeVersion = manifest.engines?.node; |       // See https://docs.volta.sh/guide/understanding#managing-your-project
 | ||||||
|  |       if (manifest.volta?.node) { | ||||||
|  |         return manifest.volta.node; | ||||||
|  |       } | ||||||
| 
 | 
 | ||||||
|       // if contents are an object, we parsed JSON
 |       if (manifest.engines?.node) { | ||||||
|  |         return manifest.engines.node; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Support Volta workspaces.
 | ||||||
|  |       // See https://docs.volta.sh/advanced/workspaces
 | ||||||
|  |       if (manifest.volta?.extends) { | ||||||
|  |         const extendedFilePath = path.resolve( | ||||||
|  |           path.dirname(versionFilePath), | ||||||
|  |           manifest.volta.extends | ||||||
|  |         ); | ||||||
|  |         core.info('Resolving node version from ' + extendedFilePath); | ||||||
|  |         return getNodeVersionFromFile(extendedFilePath); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // If contents are an object, we parsed JSON
 | ||||||
|       // this can happen if node-version-file is a package.json
 |       // this can happen if node-version-file is a package.json
 | ||||||
|       // yet contains no volta.node or engines.node
 |       // yet contains no volta.node or engines.node
 | ||||||
|       //
 |       //
 | ||||||
|       // if node-version file is _not_ json, control flow
 |       // If node-version file is _not_ JSON, control flow
 | ||||||
|       // will not have reached these lines.
 |       // will not have reached these lines.
 | ||||||
|       //
 |       //
 | ||||||
|       // And because we've reached here, we know the contents
 |       // And because we've reached here, we know the contents
 | ||||||
|       // *are* JSON, so no further string parsing makes sense.
 |       // *are* JSON, so no further string parsing makes sense.
 | ||||||
|       if (!nodeVersion) { |       return null; | ||||||
|         return null; |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } catch { |   } catch { | ||||||
|     core.info('Node version file is not JSON file'); |     core.info('Node version file is not JSON file'); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (!nodeVersion) { |   const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m); | ||||||
|     const found = contents.match(/^(?:node(js)?\s+)?v?(?<version>[^\s]+)$/m); |   return found?.groups?.version ?? contents.trim(); | ||||||
|     nodeVersion = found?.groups?.version; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // In the case of an unknown format,
 |  | ||||||
|   // return as is and evaluate the version separately.
 |  | ||||||
|   if (!nodeVersion) nodeVersion = contents.trim(); |  | ||||||
| 
 |  | ||||||
|   return nodeVersion as string; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function printEnvDetailsAndSetOutput() { | export async function printEnvDetailsAndSetOutput() { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user