Skip to content

Commit a1840d6

Browse files
author
Robert Jackson
authored
Merge pull request #107 from volta-cli/support-pinning-in-subdirs
Add `package-json-path` input to specify location of `package.json`
2 parents d0f3586 + 2f8c383 commit a1840d6

File tree

6 files changed

+112
-31
lines changed

6 files changed

+112
-31
lines changed

.github/workflows/CI.yml

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,7 @@ jobs:
175175
- run: ./action/tests/check-registry.sh 'https://some.path.here.com/lol/'
176176

177177
test-specific-variant:
178-
runs-on: "${{ matrix.os }}-latest"
179-
180-
strategy:
181-
matrix:
182-
os: [ubuntu]
178+
runs-on: "ubuntu-latest"
183179

184180
steps:
185181
- uses: actions/checkout@v3
@@ -200,3 +196,62 @@ jobs:
200196
- run: ./action/tests/check-version.sh 'node' 'v12.16.1'
201197
- run: ./action/tests/check-version.sh 'npm' '7.5.2'
202198
- run: ./action/tests/check-version.sh 'yarn' '1.19.1'
199+
200+
test-js-project-in-subdir-no-options:
201+
runs-on: "ubuntu-latest"
202+
203+
steps:
204+
- uses: actions/checkout@v3
205+
with:
206+
path: action
207+
208+
- uses: actions/checkout@v3
209+
with:
210+
ref: 'branch-for-testing-overriding-pinned-projects-in-ci'
211+
path: 'js-stuff'
212+
213+
- run: npm ci
214+
working-directory: ./action
215+
- run: npm run build
216+
working-directory: ./action
217+
- uses: ./action
218+
219+
- run: ./action/tests/log-info.sh
220+
- run: ./action/tests/check-version.sh 'volta' 'current'
221+
- run: ../action/tests/check-version.sh 'node' 'v12.16.1'
222+
working-directory: ./js-stuff
223+
- run: ../action/tests/check-version.sh 'yarn' '1.22.4'
224+
working-directory: ./js-stuff
225+
226+
test-js-project-in-subdir-with-overrides:
227+
runs-on: "ubuntu-latest"
228+
229+
steps:
230+
- uses: actions/checkout@v3
231+
with:
232+
path: action
233+
234+
- uses: actions/checkout@v3
235+
with:
236+
ref: 'branch-for-testing-overriding-pinned-projects-in-ci'
237+
path: 'js-stuff'
238+
239+
- run: npm ci
240+
working-directory: ./action
241+
- run: npm run build
242+
working-directory: ./action
243+
- uses: ./action
244+
with:
245+
package-json-path: 'js-stuff/package.json'
246+
node-version: 12.14.0
247+
npm-version: 7.5.2
248+
yarn-version: 1.22.0
249+
250+
- run: ./action/tests/log-info.sh
251+
- run: ./action/tests/check-version.sh 'volta' 'current'
252+
- run: ../action/tests/check-version.sh 'node' 'v12.14.0'
253+
working-directory: ./js-stuff
254+
- run: ../action/tests/check-version.sh 'npm' '7.5.2'
255+
working-directory: ./js-stuff
256+
- run: ../action/tests/check-version.sh 'yarn' '1.22.0'
257+
working-directory: ./js-stuff

action.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: 'Setup a Node.js environment with Volta'
33
author: 'Robert Jackson <[email protected]>'
44
inputs:
55
volta-version:
6-
description: 'Version Spec of the volta version to use. Examples: 0.6.x, 10.15.1, >=10.15.0'
6+
description: 'Version of `volta` to fetch and setup. Examples: 0.6.0, 10.15.1, >=10.15.0'
77
default: ''
88
node-version:
99
description: 'Version Spec of the node version to use. Examples: 10.6.x, 10.15.1, >=10.15.0'
@@ -14,6 +14,9 @@ inputs:
1414
yarn-version:
1515
description: 'Version Spec of the yarn version to use. Examples: 1.6.x, 10.15.1, >=10.15.0'
1616
default: ''
17+
package-json-path:
18+
description: 'The path to the package.json to update when using an explicit `node-version` | `yarn-version` | `npm-version` override. By default, we will use `package.json` in the checkout root.'
19+
default: ''
1720
variant:
1821
description: 'Specific variant to install. Example: providing the variant "linux-openssl-rhel", which will target installing the volta-${version}-linux-openssl-rhel.tar.gz tarball'
1922
default: ''

package-lock.json

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
"eslint": "^8.23.0",
4848
"eslint-config-prettier": "^8.5.0",
4949
"eslint-plugin-prettier": "^4.2.1",
50-
"find-up": "^5.0.0",
5150
"jest": "^28.1.3",
5251
"jest-circus": "^28.1.3",
5352
"nock": "^13.2.9",

src/index.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as core from '@actions/core';
2-
import findUp from 'find-up';
2+
import { existsSync } from 'fs';
3+
import { dirname } from 'path';
34
import * as installer from './installer';
45
import * as registry from './registry';
56
import addMatchers from './matchers';
@@ -9,39 +10,56 @@ async function run(): Promise<void> {
910
const authToken = core.getInput('token', { required: false });
1011
const voltaVersion = core.getInput('volta-version', { required: false });
1112
const variant = core.getInput('variant', { required: false });
13+
let packageJSONPath = core.getInput('package-json-path', { required: false });
14+
const hasPackageJSONPath = packageJSONPath !== '';
15+
16+
if (hasPackageJSONPath && !existsSync(packageJSONPath)) {
17+
core.setFailed(
18+
`custom \`package-json-path: ${packageJSONPath}\` was specified, but a file was not found at \`${packageJSONPath}\``
19+
);
20+
return;
21+
} else if (!hasPackageJSONPath) {
22+
packageJSONPath = 'package.json';
23+
}
24+
25+
const hasPackageJSON = existsSync(packageJSONPath);
26+
const workingDirectory = dirname(packageJSONPath);
1227

1328
await installer.getVolta({ versionSpec: voltaVersion, authToken, variant });
1429

15-
const hasPackageJSON = await findUp('package.json');
1630
const nodeVersion = core.getInput('node-version', { required: false });
1731
if (nodeVersion !== '') {
1832
core.info(`installing Node ${nodeVersion === 'true' ? '' : nodeVersion}`);
1933
await installer.installNode(nodeVersion);
2034

2135
if (hasPackageJSON) {
22-
await installer.pinNode(nodeVersion);
36+
await installer.pinNode(workingDirectory, nodeVersion);
37+
} else {
38+
core.info(
39+
`no \`package.json\` file found, if your \`package.json\` is located somewhere other than the root of the working directory you can specify \`package-json-path\` to provide that location. `
40+
);
2341
}
2442
}
2543

2644
const npmVersion = core.getInput('npm-version', { required: false });
2745
if (npmVersion !== '') {
28-
core.info(`installing NPM ${npmVersion === 'true' ? '' : npmVersion}`);
46+
core.info(`installing NPM ${npmVersion.toUpperCase() === 'TRUE' ? '' : npmVersion}`);
2947
await installer.installNpm(npmVersion);
3048

3149
// cannot pin `npm` when `node` is not pinned as well
3250
if (nodeVersion !== '' && hasPackageJSON) {
33-
await installer.pinNpm(npmVersion);
51+
await installer.pinNpm(workingDirectory, npmVersion);
3452
}
3553
}
3654

3755
const yarnVersion = core.getInput('yarn-version', { required: false });
3856
if (yarnVersion !== '') {
39-
core.info(`installing Yarn ${yarnVersion === 'true' ? '' : yarnVersion}`);
57+
core.info(`installing Yarn ${yarnVersion.toUpperCase() === 'TRUE' ? '' : yarnVersion}`);
4058
await installer.installYarn(yarnVersion);
4159

4260
// cannot pin `yarn` when `node` is not pinned as well
4361
if (nodeVersion !== '' && hasPackageJSON) {
44-
await installer.pinYarn(yarnVersion);
62+
await installer.pinYarn(workingDirectory, yarnVersion);
4563
}
4664
}
4765

src/installer.ts

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -220,46 +220,53 @@ async function setupVolta(version: string, voltaHome: string): Promise<void> {
220220
}
221221
}
222222

223-
export async function execVolta(specifiedArgs: string[]): Promise<void> {
223+
export async function execVolta(workingDirectory: string, specifiedArgs: string[]): Promise<void> {
224224
const args = [...specifiedArgs];
225-
let options;
225+
const options: ExecOptions = {
226+
cwd: workingDirectory,
227+
};
226228

227229
if (core.isDebug()) {
228230
args.unshift('--verbose');
229231

230-
options = {
231-
env: {
232-
VOLTA_LOGLEVEL: 'debug',
233-
RUST_STACKTRACE: 'full',
234-
},
232+
options.env = {
233+
VOLTA_LOGLEVEL: 'debug',
234+
RUST_STACKTRACE: 'full',
235+
236+
// add `process.env` (otherwise specifying `env` will cause us to no
237+
// longer inherit `process.env`)
238+
...process.env,
235239
};
236240
}
237241

238242
await exec('volta', args, options);
239243
}
240244

241245
export async function installNode(version: string): Promise<void> {
242-
await execVolta(['install', `node${version === 'true' ? '' : `@${version}`}`]);
246+
// using `.` here because `volta install` doesn't care about the working directory at all
247+
await execVolta('.', ['install', `node${version === 'true' ? '' : `@${version}`}`]);
243248
}
244249

245250
export async function installNpm(version: string): Promise<void> {
246-
await execVolta(['install', `npm${version === 'true' ? '' : `@${version}`}`]);
251+
// using `.` here because `volta install` doesn't care about the working directory at all
252+
await execVolta('.', ['install', `npm${version === 'true' ? '' : `@${version}`}`]);
247253
}
248254

249255
export async function installYarn(version: string): Promise<void> {
250-
await execVolta(['install', `yarn${version === 'true' ? '' : `@${version}`}`]);
256+
// using `.` here because `volta install` doesn't care about the working directory at all
257+
await execVolta('.', ['install', `yarn${version === 'true' ? '' : `@${version}`}`]);
251258
}
252259

253-
export async function pinNode(version: string): Promise<void> {
254-
await execVolta(['pin', `node${version === 'true' ? '' : `@${version}`}`]);
260+
export async function pinNode(workingDirectory: string, version: string): Promise<void> {
261+
await execVolta(workingDirectory, ['pin', `node${version === 'true' ? '' : `@${version}`}`]);
255262
}
256263

257-
export async function pinNpm(version: string): Promise<void> {
258-
await execVolta(['pin', `npm${version === 'true' ? '' : `@${version}`}`]);
264+
export async function pinNpm(workingDirectory: string, version: string): Promise<void> {
265+
await execVolta(workingDirectory, ['pin', `npm${version === 'true' ? '' : `@${version}`}`]);
259266
}
260267

261-
export async function pinYarn(version: string): Promise<void> {
262-
await execVolta(['pin', `yarn${version === 'true' ? '' : `@${version}`}`]);
268+
export async function pinYarn(workingDirectory: string, version: string): Promise<void> {
269+
await execVolta(workingDirectory, ['pin', `yarn${version === 'true' ? '' : `@${version}`}`]);
263270
}
264271

265272
export async function getVoltaVersion(versionSpec: string, authToken: string): Promise<string> {

0 commit comments

Comments
 (0)