Skip to content

Commit

Permalink
Merge master into releases/v1
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Gross committed Nov 15, 2019
1 parent 86dff56 commit 6491e51
Show file tree
Hide file tree
Showing 18 changed files with 2,418 additions and 168 deletions.
16 changes: 16 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"env": { "node": true, "jest": true },
"parser": "@typescript-eslint/parser",
"parserOptions": { "ecmaVersion": 2020, "sourceType": "module" },
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"plugin:prettier/recommended",
"prettier/@typescript-eslint"
],
"plugins": ["@typescript-eslint", "jest"]
}
26 changes: 24 additions & 2 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: Tests

on:
pull_request:
branches:
- master
paths-ignore:
- '**.md'
push:
branches:
- master
Expand All @@ -10,22 +15,39 @@ on:
jobs:
test:
name: Test on ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v1

- uses: actions/setup-node@v1
with:
node-version: '12.x'

- name: Get npm cache directory
id: npm-cache
run: |
echo "::set-output name=dir::$(npm config get cache)"
- uses: actions/cache@v1
with:
path: ${{ steps.npm-cache.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- run: npm ci

- name: Prettier Format Check
run: npm run format-check

- name: ESLint Check
run: npm run lint

- name: Build & Test
run: npm run test
25 changes: 11 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Create a workflow `.yml` file in your repositories `.github/workflows` directory
### Example workflow

```yaml
name: Example Caching with npm
name: Caching Primes

on: push

Expand All @@ -39,22 +39,19 @@ jobs:
steps:
- uses: actions/checkout@v1

- name: Cache node modules
- name: Cache Primes
id: cache-primes
uses: actions/cache@v1
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
path: prime-numbers
key: ${{ runner.os }}-primes

- name: Install Dependencies
run: npm install
- name: Generate Prime Numbers
if: steps.cache-primes.outputs.cache-hit != 'true'
run: /generate-primes.sh -d prime-numbers

- name: Build
run: npm run build

- name: Test
run: npm run test
- name: Use Prime Numbers
run: /primes.sh -d prime-numbers
```
## Ecosystem Examples
Expand All @@ -78,7 +75,7 @@ steps:
id: cache
with:
path: path/to/dependencies
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles')}}
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
Expand Down
1 change: 1 addition & 0 deletions __tests__/__fixtures__/helloWorld.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello world
226 changes: 226 additions & 0 deletions __tests__/actionUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
import * as core from "@actions/core";
import * as os from "os";
import * as path from "path";

import { Events, Outputs, State } from "../src/constants";
import { ArtifactCacheEntry } from "../src/contracts";
import * as actionUtils from "../src/utils/actionUtils";

jest.mock("@actions/core");
jest.mock("os");

afterEach(() => {
delete process.env[Events.Key];
});

test("getArchiveFileSize returns file size", () => {
const filePath = path.join(__dirname, "__fixtures__", "helloWorld.txt");

const size = actionUtils.getArchiveFileSize(filePath);

expect(size).toBe(11);
});

test("isExactKeyMatch with undefined cache entry returns false", () => {
const key = "linux-rust";
const cacheEntry = undefined;

expect(actionUtils.isExactKeyMatch(key, cacheEntry)).toBe(false);
});

test("isExactKeyMatch with empty cache entry returns false", () => {
const key = "linux-rust";
const cacheEntry: ArtifactCacheEntry = {};

expect(actionUtils.isExactKeyMatch(key, cacheEntry)).toBe(false);
});

test("isExactKeyMatch with different keys returns false", () => {
const key = "linux-rust";
const cacheEntry: ArtifactCacheEntry = {
cacheKey: "linux-"
};

expect(actionUtils.isExactKeyMatch(key, cacheEntry)).toBe(false);
});

test("isExactKeyMatch with different key accents returns false", () => {
const key = "linux-áccent";
const cacheEntry: ArtifactCacheEntry = {
cacheKey: "linux-accent"
};

expect(actionUtils.isExactKeyMatch(key, cacheEntry)).toBe(false);
});

test("isExactKeyMatch with same key returns true", () => {
const key = "linux-rust";
const cacheEntry: ArtifactCacheEntry = {
cacheKey: "linux-rust"
};

expect(actionUtils.isExactKeyMatch(key, cacheEntry)).toBe(true);
});

test("isExactKeyMatch with same key and different casing returns true", () => {
const key = "linux-rust";
const cacheEntry: ArtifactCacheEntry = {
cacheKey: "LINUX-RUST"
};

expect(actionUtils.isExactKeyMatch(key, cacheEntry)).toBe(true);
});

test("setOutputAndState with undefined entry to set cache-hit output", () => {
const key = "linux-rust";
const cacheEntry = undefined;

const setOutputMock = jest.spyOn(core, "setOutput");
const saveStateMock = jest.spyOn(core, "saveState");

actionUtils.setOutputAndState(key, cacheEntry);

expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "false");
expect(setOutputMock).toHaveBeenCalledTimes(1);

expect(saveStateMock).toHaveBeenCalledTimes(0);
});

test("setOutputAndState with exact match to set cache-hit output and state", () => {
const key = "linux-rust";
const cacheEntry: ArtifactCacheEntry = {
cacheKey: "linux-rust"
};

const setOutputMock = jest.spyOn(core, "setOutput");
const saveStateMock = jest.spyOn(core, "saveState");

actionUtils.setOutputAndState(key, cacheEntry);

expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "true");
expect(setOutputMock).toHaveBeenCalledTimes(1);

expect(saveStateMock).toHaveBeenCalledWith(
State.CacheResult,
JSON.stringify(cacheEntry)
);
expect(saveStateMock).toHaveBeenCalledTimes(1);
});

test("setOutputAndState with no exact match to set cache-hit output and state", () => {
const key = "linux-rust";
const cacheEntry: ArtifactCacheEntry = {
cacheKey: "linux-rust-bb828da54c148048dd17899ba9fda624811cfb43"
};

const setOutputMock = jest.spyOn(core, "setOutput");
const saveStateMock = jest.spyOn(core, "saveState");

actionUtils.setOutputAndState(key, cacheEntry);

expect(setOutputMock).toHaveBeenCalledWith(Outputs.CacheHit, "false");
expect(setOutputMock).toHaveBeenCalledTimes(1);

expect(saveStateMock).toHaveBeenCalledWith(
State.CacheResult,
JSON.stringify(cacheEntry)
);
expect(saveStateMock).toHaveBeenCalledTimes(1);
});

test("getCacheState with no state returns undefined", () => {
const getStateMock = jest.spyOn(core, "getState");
getStateMock.mockImplementation(() => {
return "";
});

const state = actionUtils.getCacheState();

expect(state).toBe(undefined);

expect(getStateMock).toHaveBeenCalledWith(State.CacheResult);
expect(getStateMock).toHaveBeenCalledTimes(1);
});

test("getCacheState with valid state", () => {
const cacheEntry: ArtifactCacheEntry = {
cacheKey: "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43",
scope: "refs/heads/master",
creationTime: "2019-11-13T19:18:02+00:00",
archiveLocation: "www.actionscache.test/download"
};
const getStateMock = jest.spyOn(core, "getState");
getStateMock.mockImplementation(() => {
return JSON.stringify(cacheEntry);
});

const state = actionUtils.getCacheState();

expect(state).toEqual(cacheEntry);

expect(getStateMock).toHaveBeenCalledWith(State.CacheResult);
expect(getStateMock).toHaveBeenCalledTimes(1);
});

test("isValidEvent returns false for unknown event", () => {
const event = "foo";
process.env[Events.Key] = event;

const isValidEvent = actionUtils.isValidEvent();

expect(isValidEvent).toBe(false);
});

test("resolvePath with no ~ in path", () => {
const filePath = ".cache/yarn";

const resolvedPath = actionUtils.resolvePath(filePath);

const expectedPath = path.resolve(filePath);
expect(resolvedPath).toBe(expectedPath);
});

test("resolvePath with ~ in path", () => {
const filePath = "~/.cache/yarn";

const homedir = jest.requireActual("os").homedir();
const homedirMock = jest.spyOn(os, "homedir");
homedirMock.mockImplementation(() => {
return homedir;
});

const resolvedPath = actionUtils.resolvePath(filePath);

const expectedPath = path.join(homedir, ".cache/yarn");
expect(resolvedPath).toBe(expectedPath);
});

test("resolvePath with home not found", () => {
const filePath = "~/.cache/yarn";
const homedirMock = jest.spyOn(os, "homedir");
homedirMock.mockImplementation(() => {
return "";
});

expect(() => actionUtils.resolvePath(filePath)).toThrow(
"Unable to resolve `~` to HOME"
);
});

test("isValidEvent returns true for push event", () => {
const event = Events.Push;
process.env[Events.Key] = event;

const isValidEvent = actionUtils.isValidEvent();

expect(isValidEvent).toBe(true);
});

test("isValidEvent returns true for pull request event", () => {
const event = Events.PullRequest;
process.env[Events.Key] = event;

const isValidEvent = actionUtils.isValidEvent();

expect(isValidEvent).toBe(true);
});
22 changes: 0 additions & 22 deletions __tests__/main.test.ts

This file was deleted.

Loading

0 comments on commit 6491e51

Please sign in to comment.