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

Implement "check-latest" flag to check if pre-cached version is latest one #165

Merged
merged 6 commits into from
Jun 29, 2020
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
2 changes: 1 addition & 1 deletion .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: [ubuntu-latest, windows-latest]
operating-system: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- name: Setup node 12
Expand Down
88 changes: 70 additions & 18 deletions .github/workflows/versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,88 @@ on:
- '**.md'

jobs:
versions:
local-cache:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest]
defaults:
run:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10, 12, 14]
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: ./
with:
node-version: ${{ matrix.node-version }}
- name: Verify node and npm
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash

manifest:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10.15, 12.16.0, 14.2.0]
steps:
- uses: actions/checkout@v2
# test version that falls through to node dist
- name: Setup node 11 from dist
- name: Setup Node
uses: ./
with:
node-version: 11
node-version: ${{ matrix.node-version }}
- name: Verify node and npm
run: __tests__/verify-node.sh 11
# test old versions which didn't have npm and layout different
- name: Setup node 0.12.18 from dist
uses: ./
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash

check-latest:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10, 11, 12, 14]
steps:
- uses: actions/checkout@v2
- name: Setup Node and check latest
uses: ./
with:
node-version: 0.12.18
- name: Verify node
node-version: ${{ matrix.node-version }}
check-latest: true
- name: Verify node and npm
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash
run: __tests__/verify-node.sh 0.12.18 SKIP_NPM
# test version from node manifest
- name: Setup node 12.16.2 from manifest

node-dist:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [11, 13]
steps:
- uses: actions/checkout@v2
- name: Setup Node from dist
uses: ./
with:
node-version: 12.16.2
node-version: ${{ matrix.node-version }}
- name: Verify node and npm
run: __tests__/verify-node.sh 12
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash

old-versions:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
# test old versions which didn't have npm and layout different
- name: Setup node 0.12.18 from dist
uses: ./
with:
node-version: 0.12.18
- name: Verify node
run: __tests__/verify-node.sh 0.12.18 SKIP_NPM
shell: bash
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ steps:
- run: npm test
```

Check latest version:
> In basic example, without `check-latest` flag, the action tries to resolve version from local cache firstly and download only if it is not found. Local cache on image is updated with a couple of weeks latency.
`check-latest` flag forces the action to check if the cached version is the latest one. It reduces latency significantly but it is much more likely to incur version downloading.
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- run: npm install
- run: npm test
```

Matrix Testing:
```yaml
jobs:
Expand Down
155 changes: 154 additions & 1 deletion __tests__/installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import path from 'path';
import * as main from '../src/main';
import * as im from '../src/installer';
import * as auth from '../src/authutil';
import {context} from '@actions/github';

let nodeTestManifest = require('./data/versions-manifest.json');
let nodeTestDist = require('./data/node-dist-index.json');
Expand All @@ -24,6 +25,7 @@ describe('setup-node', () => {
let findSpy: jest.SpyInstance;
let cnSpy: jest.SpyInstance;
let logSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
let getManifestSpy: jest.SpyInstance;
let getDistSpy: jest.SpyInstance;
let platSpy: jest.SpyInstance;
Expand Down Expand Up @@ -77,8 +79,9 @@ describe('setup-node', () => {

// writes
cnSpy = jest.spyOn(process.stdout, 'write');
logSpy = jest.spyOn(console, 'log');
logSpy = jest.spyOn(core, 'info');
dbgSpy = jest.spyOn(core, 'debug');
warningSpy = jest.spyOn(core, 'warning');
cnSpy.mockImplementation(line => {
// uncomment to debug
// process.stderr.write('write:' + line + '\n');
Expand Down Expand Up @@ -333,4 +336,154 @@ describe('setup-node', () => {

expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
});

describe('check-latest flag', () => {
it('use local version and dont check manifest if check-latest is not specified', async () => {
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = '12';
inputs['check-latest'] = 'false';

const toolPath = path.normalize('/cache/node/12.16.1/x64');
findSpy.mockReturnValue(toolPath);
await main.run();

expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(logSpy).not.toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
});

it('check latest version and resolve it from local cache', async () => {
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = '12';
inputs['check-latest'] = 'true';

const toolPath = path.normalize('/cache/node/12.16.2/x64');
findSpy.mockReturnValue(toolPath);
dlSpy.mockImplementation(async () => '/some/temp/path');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);

await main.run();

expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
});

it('check latest version and install it from manifest', async () => {
os.platform = 'linux';
os.arch = 'x64';

inputs['node-version'] = '12';
inputs['check-latest'] = 'true';

findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/node/12.16.2/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
const expectedUrl =
'https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz';

await main.run();

expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
expect(logSpy).toHaveBeenCalledWith(
`Acquiring 12.16.2 from ${expectedUrl}`
);
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
});

it('fallback to dist if version if not found in manifest', async () => {
os.platform = 'linux';
os.arch = 'x64';

// a version which is not in the manifest but is in node dist
let versionSpec = '11';

inputs['node-version'] = versionSpec;
inputs['check-latest'] = 'true';
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';

// ... but not in the local cache
findSpy.mockImplementation(() => '');

dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/node/11.11.0/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);

await main.run();

let expPath = path.join(toolPath, 'bin');

expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith(
`Failed to resolve version ${versionSpec} from manifest`
);
expect(logSpy).toHaveBeenCalledWith(
`Attempting to download ${versionSpec}...`
);
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});

it('fallback to dist if manifest is not available', async () => {
os.platform = 'linux';
os.arch = 'x64';

// a version which is not in the manifest but is in node dist
let versionSpec = '12';

inputs['node-version'] = versionSpec;
inputs['check-latest'] = 'true';
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';

// ... but not in the local cache
findSpy.mockImplementation(() => '');
getManifestSpy.mockImplementation(() => {
throw new Error('Unable to download manifest');
});

dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/node/12.11.0/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);

await main.run();

let expPath = path.join(toolPath, 'bin');

expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith(
'Unable to resolve version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith(
`Failed to resolve version ${versionSpec} from manifest`
);
expect(logSpy).toHaveBeenCalledWith(
`Attempting to download ${versionSpec}...`
);
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
});
});
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ inputs:
default: 'false'
node-version:
description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0'
check-latest:
description: 'Set this option if you want the action to check for the latest available version that satisfies the version spec'
default: false
registry-url:
description: 'Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN'
scope:
Expand Down
Loading