Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add package-json-path input to specify location of package.json #107

Merged
merged 1 commit into from
Sep 9, 2022
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
65 changes: 60 additions & 5 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,7 @@ jobs:
- run: ./action/tests/check-registry.sh 'https://some.path.here.com/lol/'

test-specific-variant:
runs-on: "${{ matrix.os }}-latest"

strategy:
matrix:
os: [ubuntu]
runs-on: "ubuntu-latest"

steps:
- uses: actions/checkout@v3
Expand All @@ -200,3 +196,62 @@ jobs:
- run: ./action/tests/check-version.sh 'node' 'v12.16.1'
- run: ./action/tests/check-version.sh 'npm' '7.5.2'
- run: ./action/tests/check-version.sh 'yarn' '1.19.1'

test-js-project-in-subdir-no-options:
runs-on: "ubuntu-latest"

steps:
- uses: actions/checkout@v3
with:
path: action

- uses: actions/checkout@v3
with:
ref: 'branch-for-testing-overriding-pinned-projects-in-ci'
path: 'js-stuff'

- run: npm ci
working-directory: ./action
- run: npm run build
working-directory: ./action
- uses: ./action

- run: ./action/tests/log-info.sh
- run: ./action/tests/check-version.sh 'volta' 'current'
- run: ../action/tests/check-version.sh 'node' 'v12.16.1'
working-directory: ./js-stuff
- run: ../action/tests/check-version.sh 'yarn' '1.22.4'
working-directory: ./js-stuff

test-js-project-in-subdir-with-overrides:
runs-on: "ubuntu-latest"

steps:
- uses: actions/checkout@v3
with:
path: action

- uses: actions/checkout@v3
with:
ref: 'branch-for-testing-overriding-pinned-projects-in-ci'
path: 'js-stuff'

- run: npm ci
working-directory: ./action
- run: npm run build
working-directory: ./action
- uses: ./action
with:
package-json-path: 'js-stuff/package.json'
node-version: 12.14.0
npm-version: 7.5.2
yarn-version: 1.22.0

- run: ./action/tests/log-info.sh
- run: ./action/tests/check-version.sh 'volta' 'current'
- run: ../action/tests/check-version.sh 'node' 'v12.14.0'
working-directory: ./js-stuff
- run: ../action/tests/check-version.sh 'npm' '7.5.2'
working-directory: ./js-stuff
- run: ../action/tests/check-version.sh 'yarn' '1.22.0'
working-directory: ./js-stuff
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: 'Setup a Node.js environment with Volta'
author: 'Robert Jackson <[email protected]>'
inputs:
volta-version:
description: 'Version Spec of the volta version to use. Examples: 0.6.x, 10.15.1, >=10.15.0'
description: 'Version of `volta` to fetch and setup. Examples: 0.6.0, 10.15.1, >=10.15.0'
default: ''
node-version:
description: 'Version Spec of the node version to use. Examples: 10.6.x, 10.15.1, >=10.15.0'
Expand All @@ -14,6 +14,9 @@ inputs:
yarn-version:
description: 'Version Spec of the yarn version to use. Examples: 1.6.x, 10.15.1, >=10.15.0'
default: ''
package-json-path:
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.'
default: ''
variant:
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'
default: ''
Expand Down
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
"eslint": "^8.23.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"find-up": "^5.0.0",
"jest": "^28.1.3",
"jest-circus": "^28.1.3",
"nock": "^13.2.9",
Expand Down
32 changes: 25 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as core from '@actions/core';
import findUp from 'find-up';
import { existsSync } from 'fs';
import { dirname } from 'path';
import * as installer from './installer';
import * as registry from './registry';
import addMatchers from './matchers';
Expand All @@ -9,39 +10,56 @@ async function run(): Promise<void> {
const authToken = core.getInput('token', { required: false });
const voltaVersion = core.getInput('volta-version', { required: false });
const variant = core.getInput('variant', { required: false });
let packageJSONPath = core.getInput('package-json-path', { required: false });
const hasPackageJSONPath = packageJSONPath !== '';

if (hasPackageJSONPath && !existsSync(packageJSONPath)) {
core.setFailed(
`custom \`package-json-path: ${packageJSONPath}\` was specified, but a file was not found at \`${packageJSONPath}\``
);
return;
} else if (!hasPackageJSONPath) {
packageJSONPath = 'package.json';
}

const hasPackageJSON = existsSync(packageJSONPath);
const workingDirectory = dirname(packageJSONPath);

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

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

if (hasPackageJSON) {
await installer.pinNode(nodeVersion);
await installer.pinNode(workingDirectory, nodeVersion);
} else {
core.info(
`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. `
);
}
}

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

// cannot pin `npm` when `node` is not pinned as well
if (nodeVersion !== '' && hasPackageJSON) {
await installer.pinNpm(npmVersion);
await installer.pinNpm(workingDirectory, npmVersion);
}
}

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

// cannot pin `yarn` when `node` is not pinned as well
if (nodeVersion !== '' && hasPackageJSON) {
await installer.pinYarn(yarnVersion);
await installer.pinYarn(workingDirectory, yarnVersion);
}
}

Expand Down
39 changes: 23 additions & 16 deletions src/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,46 +220,53 @@ async function setupVolta(version: string, voltaHome: string): Promise<void> {
}
}

export async function execVolta(specifiedArgs: string[]): Promise<void> {
export async function execVolta(workingDirectory: string, specifiedArgs: string[]): Promise<void> {
const args = [...specifiedArgs];
let options;
const options: ExecOptions = {
cwd: workingDirectory,
};

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

options = {
env: {
VOLTA_LOGLEVEL: 'debug',
RUST_STACKTRACE: 'full',
},
options.env = {
VOLTA_LOGLEVEL: 'debug',
RUST_STACKTRACE: 'full',

// add `process.env` (otherwise specifying `env` will cause us to no
// longer inherit `process.env`)
...process.env,
};
}

await exec('volta', args, options);
}

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

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

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

export async function pinNode(version: string): Promise<void> {
await execVolta(['pin', `node${version === 'true' ? '' : `@${version}`}`]);
export async function pinNode(workingDirectory: string, version: string): Promise<void> {
await execVolta(workingDirectory, ['pin', `node${version === 'true' ? '' : `@${version}`}`]);
}

export async function pinNpm(version: string): Promise<void> {
await execVolta(['pin', `npm${version === 'true' ? '' : `@${version}`}`]);
export async function pinNpm(workingDirectory: string, version: string): Promise<void> {
await execVolta(workingDirectory, ['pin', `npm${version === 'true' ? '' : `@${version}`}`]);
}

export async function pinYarn(version: string): Promise<void> {
await execVolta(['pin', `yarn${version === 'true' ? '' : `@${version}`}`]);
export async function pinYarn(workingDirectory: string, version: string): Promise<void> {
await execVolta(workingDirectory, ['pin', `yarn${version === 'true' ? '' : `@${version}`}`]);
}

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