From dc8541739ae7fe300ac99c70459cdc50e08ed4e3 Mon Sep 17 00:00:00 2001 From: Shohei Ueda <30958501+peaceiris@users.noreply.github.com> Date: Sat, 21 Sep 2019 10:41:21 +0900 Subject: [PATCH] Feat: Support macOS and Windows, migrate JavaScript to TypeScript (#32) - Support macOS and Windows (Close #24 ) - Refactoring - Error handling - TypeScript - Prettier (Close #29 ) - GHA: Add upload-artifact step for test coverage - deps: Install husky --- .editorconfig | 9 + .eslintrc.json | 34 ++- .github/workflows/test.yml | 22 +- .prettierrc.json | 11 + .vscode/settings.json | 3 + README.md | 16 +- __tests__/get-os.test.ts | 18 ++ __tests__/get-url.test.ts | 22 ++ __tests__/index.test.js | 23 -- jest.config.js | 11 + lib/get-latest-version.js | 39 +-- lib/get-os.js | 18 ++ lib/get-url.js | 27 ++ lib/index.js | 105 +++---- lib/installer.js | 57 ++++ node_modules/@actions/exec/package.json | 68 ++--- package-lock.json | 377 +++++++++++++++++++++++- package.json | 27 +- src/get-latest-version.ts | 19 ++ src/get-os.ts | 12 + src/get-url.ts | 31 ++ src/index.ts | 38 +++ src/installer.ts | 42 +++ tsconfig.json | 63 ++++ 24 files changed, 924 insertions(+), 168 deletions(-) create mode 100644 .editorconfig create mode 100644 .prettierrc.json create mode 100644 .vscode/settings.json create mode 100644 __tests__/get-os.test.ts create mode 100644 __tests__/get-url.test.ts delete mode 100644 __tests__/index.test.js create mode 100644 jest.config.js create mode 100644 lib/get-os.js create mode 100644 lib/get-url.js create mode 100644 lib/installer.js create mode 100644 src/get-latest-version.ts create mode 100644 src/get-os.ts create mode 100644 src/get-url.ts create mode 100644 src/index.ts create mode 100644 src/installer.ts create mode 100644 tsconfig.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0f17867 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.eslintrc.json b/.eslintrc.json index d097bf7..f8f61db 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,17 +1,19 @@ { - "env": { - "commonjs": true, - "es6": true, - "node": true - }, - "extends": "eslint:recommended", - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parserOptions": { - "ecmaVersion": 2018 - }, - "rules": { - } -} \ No newline at end of file + "env": { + "commonjs": true, + "es6": true, + "node": true + }, + "extends": "eslint:recommended", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2019 + }, + "rules": { + } +} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 518f617..b6e6ae6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,32 +8,46 @@ jobs: steps: - uses: actions/checkout@v1 + with: + fetch-depth: 1 - name: Install dependencies run: npm ci + - name: Format check + run: npm run format:check + - name: Lint run: npm run lint - # - name: Test script - # run: npm test + - name: Test + run: npm test + + - uses: actions/upload-artifact@master + with: + name: coverage + path: coverage # - name: Build production # run: npm run build test-prod: - runs-on: ubuntu-18.04 + runs-on: ${{ matrix.os }} needs: test strategy: matrix: + # os: ['ubuntu-18.04', 'macOS-10.14'] + os: ['ubuntu-18.04', 'macOS-10.14', 'windows-2019'] # hugo-version: ['latest'] # extended: [true] - hugo-version: ['latest', '0.58.2'] + hugo-version: ['latest', '0.57.2'] extended: [true, false] steps: - uses: actions/checkout@v1 + with: + fetch-depth: 1 - name: Test action uses: ./ diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..97b6e6d --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,11 @@ +{ + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": true, + "trailingComma": "none", + "bracketSpacing": false, + "arrowParens": "avoid", + "parser": "typescript" + } diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3b66410 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/README.md b/README.md index 32972a5..61607fb 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,15 @@ We can run Hugo on a virtual machine of GitHub Actions by this Hugo action. Hugo extended version and Hugo Modules are supported. -From `v2.0.0`, this Hugo action migrated to a JavaScript action. We no longer build or pull a Hugo docker image. Thanks to this change, we can complete this action less than **2 sec**. (A docker base action was taking about 1 min or more execution time to build or pull.) +From `v2.0.0`, this Hugo action migrated to a JavaScript (TypeScript) action. We no longer build or pull a Hugo docker image. Thanks to this change, we can complete this action less than **3 sec**. (A docker base action was taking about 1 min or more execution time to build or pull.) + +| OS (runs-on) | ubuntu-18.04 | macOS-10.14 | windows-2019 | +|---|:---:|:---:|:---:| +| Support | ✅️ | ✅️ | ✅️ | + +| Hugo type | Hugo Extended | Hugo Modules | Latest Hugo | +|---|:---:|:---:|:---:| +| Support | ✅️ | ✅️ | ✅️ | @@ -41,13 +49,15 @@ on: jobs: build-deploy: runs-on: ubuntu-18.04 + # runs-on: macOS-10.14 + # runs-on: windows-2019 steps: - uses: actions/checkout@master - name: Setup Hugo uses: peaceiris/actions-hugo@v2.1.0 with: - hugo-version: '0.58.2' + hugo-version: '0.58.3' - name: Build run: hugo --gc --minify --cleanDestinationDir @@ -70,7 +80,7 @@ jobs: - name: Setup Hugo uses: peaceiris/actions-hugo@v2.1.0 with: - hugo-version: '0.58.2' + hugo-version: '0.58.3' extended: true ``` diff --git a/__tests__/get-os.test.ts b/__tests__/get-os.test.ts new file mode 100644 index 0000000..d30e939 --- /dev/null +++ b/__tests__/get-os.test.ts @@ -0,0 +1,18 @@ +import getOS from '../src/get-os'; + +describe('getOS', () => { + test('test', () => { + expect(getOS('linux')).toBe('Linux'); + expect(getOS('darwin')).toBe('macOS'); + expect(getOS('win32')).toBe('Windows'); + }); + + test('test exception', () => { + // expect(() => { + // getOS("win32"); + // }).toThrowError("Windows is not supported"); + expect(() => { + getOS('centos'); + }).toThrowError('centos is not supported'); + }); +}); diff --git a/__tests__/get-url.test.ts b/__tests__/get-url.test.ts new file mode 100644 index 0000000..118a8f2 --- /dev/null +++ b/__tests__/get-url.test.ts @@ -0,0 +1,22 @@ +import getURL from '../src/get-url'; + +describe('getURL()', () => { + test('test', () => { + const baseURL = + 'https://github.com/gohugoio/hugo/releases/download/v0.58.2'; + const urlLinux = `${baseURL}/hugo_0.58.2_Linux-64bit.tar.gz`; + const urlLinuxExtended = `${baseURL}/hugo_extended_0.58.2_Linux-64bit.tar.gz`; + const urlMacOS = `${baseURL}/hugo_0.58.2_macOS-64bit.tar.gz`; + const urlWindows = `${baseURL}/hugo_0.58.2_Windows-64bit.zip`; + expect(getURL('Linux', 'false', '0.58.2')).toBe(urlLinux); + expect(getURL('Linux', 'true', '0.58.2')).toBe(urlLinuxExtended); + expect(getURL('macOS', 'false', '0.58.2')).toBe(urlMacOS); + expect(getURL('Windows', 'false', '0.58.2')).toBe(urlWindows); + }); + + // test("test exception", () => { + // expect(() => { + // getURL("Linux", "hoge", "0.58.2"); + // }).toThrowError("Invalid input (extended): hoge"); + // }); +}); diff --git a/__tests__/index.test.js b/__tests__/index.test.js deleted file mode 100644 index 9725109..0000000 --- a/__tests__/index.test.js +++ /dev/null @@ -1,23 +0,0 @@ -const wait = require('./wait'); -const process = require('process'); -const cp = require('child_process'); -const path = require('path'); - -test('throws invalid number', async() => { - await expect(wait('foo')).rejects.toThrow('milleseconds not a number'); -}); - -test('wait 500 ms', async() => { - const start = new Date(); - await wait(500); - const end = new Date(); - var delta = Math.abs(end - start); - expect(delta).toBeGreaterThan(450); -}); - -// shows how the runner will run a javascript action with env / stdout protocol -test('test runs', () => { - process.env['INPUT_MILLISECONDS'] = 500; - const ip = path.join(__dirname, 'index.js'); - console.log(cp.execSync(`node ${ip}`).toString()); -}) diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..563d4cc --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +module.exports = { + clearMocks: true, + moduleFileExtensions: ['js', 'ts'], + testEnvironment: 'node', + testMatch: ['**/*.test.ts'], + testRunner: 'jest-circus/runner', + transform: { + '^.+\\.ts$': 'ts-jest' + }, + verbose: true +} \ No newline at end of file diff --git a/lib/get-latest-version.js b/lib/get-latest-version.js index e3bdcd3..9eeadfb 100644 --- a/lib/get-latest-version.js +++ b/lib/get-latest-version.js @@ -1,21 +1,22 @@ -const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; - +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; function getLatestVersion() { - return new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest(); - const url = "https://formulae.brew.sh/api/formula/hugo.json"; - xhr.open("GET", url); - xhr.send(); - xhr.onreadystatechange = function() { - if (xhr.readyState === 4 && xhr.status === 200) { - const result = JSON.parse(xhr.responseText); - const latestVersion = result.versions.stable; - resolve(latestVersion); - } else if (xhr.readyState === 4 && xhr.status !== 200) { - reject(`ERROR: got status ${xhr.status} of ${url}`); - } - }; - }); + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + const url = 'https://formulae.brew.sh/api/formula/hugo.json'; + xhr.open('GET', url); + xhr.send(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4 && xhr.status === 200) { + const result = JSON.parse(xhr.responseText); + const latestVersion = result.versions.stable; + resolve(latestVersion); + } + else if (xhr.readyState === 4 && xhr.status !== 200) { + reject(`ERROR: got status ${xhr.status} of ${url}`); + } + }; + }); } - -module.exports = getLatestVersion; +exports.default = getLatestVersion; diff --git a/lib/get-os.js b/lib/get-os.js new file mode 100644 index 0000000..014188c --- /dev/null +++ b/lib/get-os.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function getOS(platform) { + if (platform === 'linux') { + return 'Linux'; + } + else if (platform === 'darwin') { + return 'macOS'; + } + else if (platform === 'win32') { + return 'Windows'; + // throw new Error("Windows is not supported"); + } + else { + throw new Error(`${platform} is not supported`); + } +} +exports.default = getOS; diff --git a/lib/get-url.js b/lib/get-url.js new file mode 100644 index 0000000..dc24057 --- /dev/null +++ b/lib/get-url.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function getURL(os, extended, version) { + const extendedStr = (extended) => { + if (extended === 'true') { + return 'extended_'; + } + else { + return ''; + // } else { + // throw new Error(`Invalid input (extended): ${extended}`); + } + }; + const ext = (os) => { + if (os === 'Windows') { + return 'zip'; + } + else { + return 'tar.gz'; + } + }; + const hugoName = `hugo_${extendedStr(extended)}${version}_${os}-64bit`; + const baseURL = 'https://github.com/gohugoio/hugo/releases/download'; + const url = `${baseURL}/v${version}/${hugoName}.${ext(os)}`; + return url; +} +exports.default = getURL; diff --git a/lib/index.js b/lib/index.js index d90048a..fb584bd 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,57 +1,58 @@ -const core = require("@actions/core"); -const tc = require("@actions/tool-cache"); -const io = require("@actions/io"); -const exec = require("@actions/exec"); -const getLatestVersion = require("./get-latest-version"); - +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(require("@actions/core")); +const exec = __importStar(require("@actions/exec")); +const get_latest_version_1 = __importDefault(require("./get-latest-version")); +const installer_1 = __importDefault(require("./installer")); // most @actions toolkit packages have async methods -async function run() { - try { - getLatestVersion().then( - async function(latestVersion) { - let hugoVersion = core.getInput("hugo-version"); - if (!hugoVersion || hugoVersion === "latest") { - hugoVersion = latestVersion; +function run() { + return __awaiter(this, void 0, void 0, function* () { + const dump = () => __awaiter(this, void 0, void 0, function* () { + // Show version + yield exec.exec('hugo version'); + yield exec.exec('go version'); + yield exec.exec('git --version'); + }); + try { + const hugoVersion = core.getInput('hugo-version'); + console.log(`Hugo version: ${hugoVersion}`); + if (hugoVersion === '' || hugoVersion === 'latest') { + get_latest_version_1.default().then(function (latestVersion) { + return __awaiter(this, void 0, void 0, function* () { + yield installer_1.default(latestVersion); + yield dump(); + }); + }, function (error) { + core.setFailed(error); + }); + } + else { + yield installer_1.default(hugoVersion); + yield dump(); + } } - console.log(`Hugo version: ${hugoVersion}`); - - const extended = core.getInput("extended"); - console.log(`Hugo extended: ${extended}`); - let extendedStr = ""; - if (extended === "true") { - extendedStr = "extended_"; + catch (error) { + core.setFailed(error.message); } - - console.log(`Operating System: ${process.platform}`); - - const hugoName = `hugo_${extendedStr}${hugoVersion}_Linux-64bit`; - core.debug(`hugoName: ${hugoName}`); - - const hugoURL = `https://github.com/gohugoio/hugo/releases/download/v${hugoVersion}/${hugoName}.tar.gz`; - core.debug(`hugoURL: ${hugoURL}`); - - const hugoPath = `${process.env.HOME}/bin`; - await io.mkdirP(hugoPath); - core.addPath(hugoPath); - - // Download and extract Hugo binary - const hugoTarball = await tc.downloadTool(hugoURL); - const hugoExtractedFolder = await tc.extractTar(hugoTarball, "/tmp"); - core.debug("hugoExtractedFolder:", hugoExtractedFolder); - await io.mv(`${hugoExtractedFolder}/hugo`, hugoPath); - - // Show version - await exec.exec('hugo version'); - await exec.exec('go version'); - await exec.exec('git --version'); - }, - function(error) { - core.setFailed(error); - } - ); - } catch (error) { - core.setFailed(error.message); - } + }); } - run(); diff --git a/lib/installer.js b/lib/installer.js new file mode 100644 index 0000000..2fd3641 --- /dev/null +++ b/lib/installer.js @@ -0,0 +1,57 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(require("@actions/core")); +const tc = __importStar(require("@actions/tool-cache")); +const io = __importStar(require("@actions/io")); +const get_os_1 = __importDefault(require("./get-os")); +const get_url_1 = __importDefault(require("./get-url")); +function installer(version) { + return __awaiter(this, void 0, void 0, function* () { + try { + const extended = core.getInput('extended'); + console.log(`Hugo extended: ${extended}`); + const osName = get_os_1.default(process.platform); + console.log(`Operating System: ${osName}`); + const hugoURL = get_url_1.default(osName, extended, version); + core.debug(`hugoURL: ${hugoURL}`); + const hugoPath = `${process.env.HOME}/bin`; + yield io.mkdirP(hugoPath); + core.addPath(hugoPath); + // Download and extract Hugo binary + const hugoAssets = yield tc.downloadTool(hugoURL); + let hugoBin = ''; + if (osName === 'Windows') { + const hugoExtractedFolder = yield tc.extractZip(hugoAssets, '/tmp'); + hugoBin = `${hugoExtractedFolder}/hugo.exe`; + } + else { + const hugoExtractedFolder = yield tc.extractTar(hugoAssets, '/tmp'); + hugoBin = `${hugoExtractedFolder}/hugo`; + } + yield io.mv(hugoBin, hugoPath); + } + catch (error) { + core.setFailed(error.message); + } + }); +} +exports.default = installer; diff --git a/node_modules/@actions/exec/package.json b/node_modules/@actions/exec/package.json index d9497e6..bb85262 100644 --- a/node_modules/@actions/exec/package.json +++ b/node_modules/@actions/exec/package.json @@ -1,39 +1,15 @@ { - "_from": "@actions/exec", - "_id": "@actions/exec@1.0.1", - "_inBundle": false, - "_integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ==", - "_location": "/@actions/exec", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "@actions/exec", - "name": "@actions/exec", - "escapedName": "@actions%2fexec", - "scope": "@actions", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/", - "/@actions/tool-cache" - ], - "_resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.1.tgz", - "_shasum": "1624b541165697e7008d7c87bc1f69f191263c6c", - "_spec": "@actions/exec", - "_where": "/Users/iris/Documents/repos/github.com/peaceiris/actions-hugo", - "bugs": { - "url": "https://github.com/actions/toolkit/issues" - }, - "bundleDependencies": false, - "deprecated": false, + "name": "@actions/exec", + "version": "1.0.1", "description": "Actions exec lib", - "devDependencies": { - "@actions/io": "^1.0.1" - }, + "keywords": [ + "github", + "actions", + "exec" + ], + "homepage": "https://github.com/actions/toolkit/tree/master/packages/exec", + "license": "MIT", + "main": "lib/exec.js", "directories": { "lib": "lib", "test": "__tests__" @@ -41,16 +17,6 @@ "files": [ "lib" ], - "gitHead": "a2ab4bcf78e4f7080f0d45856e6eeba16f0bbc52", - "homepage": "https://github.com/actions/toolkit/tree/master/packages/exec", - "keywords": [ - "github", - "actions", - "exec" - ], - "license": "MIT", - "main": "lib/exec.js", - "name": "@actions/exec", "publishConfig": { "access": "public" }, @@ -62,5 +28,15 @@ "test": "echo \"Error: run tests from root\" && exit 1", "tsc": "tsc" }, - "version": "1.0.1" -} + "bugs": { + "url": "https://github.com/actions/toolkit/issues" + }, + "devDependencies": { + "@actions/io": "^1.0.1" + }, + "gitHead": "a2ab4bcf78e4f7080f0d45856e6eeba16f0bbc52" + +,"_resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.1.tgz" +,"_integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ==" +,"_from": "@actions/exec@1.0.1" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1cd7c8b..cc08f44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "hugo-action", - "version": "0.1.0", + "version": "2.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -461,6 +461,12 @@ "@babel/types": "^7.3.0" } }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", @@ -486,6 +492,39 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "24.0.18", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.18.tgz", + "integrity": "sha512-jcDDXdjTcrQzdN06+TSVsPPqxvsZA/5QkYfIZlq1JMw7FdP5AZylbOc+6B/cuDurctRe+MziUMtQ3xQdrbjqyQ==", + "dev": true, + "requires": { + "@types/jest-diff": "*" + } + }, + "@types/jest-diff": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", + "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", + "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==", + "dev": true + }, + "@types/node": { + "version": "12.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", + "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", @@ -507,6 +546,49 @@ "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", "dev": true }, + "@typescript-eslint/experimental-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.3.0.tgz", + "integrity": "sha512-ry+fgd0Hh33LyzS30bIhX/a1HJpvtnecjQjWxxsZTavrRa1ymdmX7tz+7lPrPAxB018jnNzwNtog6s3OhxPTAg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.3.0", + "eslint-scope": "^5.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.3.0.tgz", + "integrity": "sha512-Dc+LAtHts0yDuusxG0NVjGvrpPy2kZauxqPbfFs0fmcMB4JhNs+WwIDMFGWeKjbGoPt/SIUC9XJ7E0ZD/f8InQ==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.3.0", + "@typescript-eslint/typescript-estree": "2.3.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.3.0.tgz", + "integrity": "sha512-WBxfwsTeCOsmQ7cLjow7lgysviBKUW34npShu7dxJYUQCbSG5nfZWZTgmQPKEc+3flpbSM7tjXjQOgETYp+njQ==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "is-glob": "^4.0.1", + "lodash.unescape": "4.0.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "abab": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.1.tgz", @@ -866,6 +948,15 @@ } } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bser": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", @@ -898,6 +989,32 @@ "unset-value": "^1.0.0" } }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1077,6 +1194,30 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "dependencies": { + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + } + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2375,6 +2516,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -2547,6 +2694,100 @@ "sshpk": "^1.7.0" } }, + "husky": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/husky/-/husky-3.0.5.tgz", + "integrity": "sha512-cKd09Jy9cDyNIvAdN2QQAP/oA21sle4FWXjIMDttailpLAYZuBE7WaPmhrkj+afS8Sj9isghAtFvWSQ0JiwOHg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cosmiconfig": "^5.2.1", + "execa": "^1.0.0", + "get-stdin": "^7.0.0", + "is-ci": "^2.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "read-pkg": "^5.1.1", + "run-node": "^1.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2763,6 +3004,12 @@ } } }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -3031,6 +3278,30 @@ "throat": "^4.0.0" } }, + "jest-circus": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-24.9.0.tgz", + "integrity": "sha512-dwkvwFtRc9Anmk1XTc+bonVL8rVMZ3CeGMoFWmv1oaQThdAgvfI9bwaFlZp+gLVphNVz6ZLfCWo3ERhS5CeVvA==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.9.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", + "stack-utils": "^1.0.1", + "throat": "^4.0.0" + } + }, "jest-config": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", @@ -3568,6 +3839,12 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -3596,12 +3873,24 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3629,6 +3918,12 @@ } } }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, "makeerror": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", @@ -3966,6 +4261,12 @@ "mimic-fn": "^1.0.0" } }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -4151,6 +4452,15 @@ "find-up": "^3.0.0" } }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -4169,6 +4479,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", + "dev": true + }, "pretty-format": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", @@ -4443,6 +4759,12 @@ "is-promise": "^2.1.0" } }, + "run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, "rxjs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", @@ -4502,6 +4824,12 @@ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -5056,6 +5384,41 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "ts-jest": { + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.1.0.tgz", + "integrity": "sha512-HEGfrIEAZKfu1pkaxB9au17b1d9b56YZSqz5eCVE8mX68+5reOvlM93xGOzzCREIov9mdH7JBG+s0UyNAqr0tQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "mkdirp": "0.x", + "resolve": "1.x", + "semver": "^5.5", + "yargs-parser": "10.x" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -5091,6 +5454,12 @@ "prelude-ls": "~1.1.2" } }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + }, "typed-rest-client": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.5.0.tgz", @@ -5100,6 +5469,12 @@ "underscore": "1.8.3" } }, + "typescript": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", + "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", + "dev": true + }, "uglify-js": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", diff --git a/package.json b/package.json index 452cdc2..d297eea 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,13 @@ "description": "Hugo setup action", "main": "lib/index.js", "scripts": { - "lint": "eslint ./lib/**/*", - "test": "jest", - "build": "npm prune --production" + "lint": "eslint ./src/**/*.ts", + "lint:fix": "eslint --fix ./src/**/*.ts", + "test": "jest --coverage --verbose", + "build": "npm prune --production", + "tsc": "tsc", + "format": "prettier --write **/*.ts", + "format:check": "prettier --check **/*.ts" }, "repository": { "type": "git", @@ -32,7 +36,22 @@ "xmlhttprequest": "^1.8.0" }, "devDependencies": { + "@types/jest": "^24.0.18", + "@types/node": "^12.7.5", + "@typescript-eslint/parser": "^2.3.0", "eslint": "^6.4.0", - "jest": "^24.9.0" + "husky": "^3.0.5", + "jest": "^24.9.0", + "jest-circus": "^24.9.0", + "prettier": "1.18.2", + "ts-jest": "^24.1.0", + "typescript": "^3.6.3" + }, + "husky": { + "skipCI": true, + "hooks": { + "pre-commit": "npm run tsc && npm run format", + "post-commit": "npm run build && git add node_modules/* && git commit -m \"deps: Husky commit correct node modules\"" + } } } diff --git a/src/get-latest-version.ts b/src/get-latest-version.ts new file mode 100644 index 0000000..b7f9382 --- /dev/null +++ b/src/get-latest-version.ts @@ -0,0 +1,19 @@ +const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; + +export default function getLatestVersion(): Promise { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + const url: string = 'https://formulae.brew.sh/api/formula/hugo.json'; + xhr.open('GET', url); + xhr.send(); + xhr.onreadystatechange = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + const result = JSON.parse(xhr.responseText); + const latestVersion: string = result.versions.stable; + resolve(latestVersion); + } else if (xhr.readyState === 4 && xhr.status !== 200) { + reject(`ERROR: got status ${xhr.status} of ${url}`); + } + }; + }); +} diff --git a/src/get-os.ts b/src/get-os.ts new file mode 100644 index 0000000..ef9d50d --- /dev/null +++ b/src/get-os.ts @@ -0,0 +1,12 @@ +export default function getOS(platform: string) { + if (platform === 'linux') { + return 'Linux'; + } else if (platform === 'darwin') { + return 'macOS'; + } else if (platform === 'win32') { + return 'Windows'; + // throw new Error("Windows is not supported"); + } else { + throw new Error(`${platform} is not supported`); + } +} diff --git a/src/get-url.ts b/src/get-url.ts new file mode 100644 index 0000000..42bd9af --- /dev/null +++ b/src/get-url.ts @@ -0,0 +1,31 @@ +export default function getURL( + os: string, + extended: string, + version: string +): string { + const extendedStr = (extended: string) => { + if (extended === 'true') { + return 'extended_'; + } else { + return ''; + // } else { + // throw new Error(`Invalid input (extended): ${extended}`); + } + }; + + const ext = (os: string) => { + if (os === 'Windows') { + return 'zip'; + } else { + return 'tar.gz'; + } + }; + + const hugoName: string = `hugo_${extendedStr( + extended + )}${version}_${os}-64bit`; + const baseURL: string = 'https://github.com/gohugoio/hugo/releases/download'; + const url: string = `${baseURL}/v${version}/${hugoName}.${ext(os)}`; + + return url; +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..18be6a6 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,38 @@ +import * as core from '@actions/core'; +import * as exec from '@actions/exec'; +import getLatestVersion from './get-latest-version'; +import installer from './installer'; + +// most @actions toolkit packages have async methods +async function run() { + const dump = async () => { + // Show version + await exec.exec('hugo version'); + await exec.exec('go version'); + await exec.exec('git --version'); + }; + + try { + const hugoVersion: string = core.getInput('hugo-version'); + console.log(`Hugo version: ${hugoVersion}`); + + if (hugoVersion === '' || hugoVersion === 'latest') { + getLatestVersion().then( + async function(latestVersion): Promise { + await installer(latestVersion); + await dump(); + }, + function(error) { + core.setFailed(error); + } + ); + } else { + await installer(hugoVersion); + await dump(); + } + } catch (error) { + core.setFailed(error.message); + } +} + +run(); diff --git a/src/installer.ts b/src/installer.ts new file mode 100644 index 0000000..517f4ef --- /dev/null +++ b/src/installer.ts @@ -0,0 +1,42 @@ +import * as core from '@actions/core'; +import * as tc from '@actions/tool-cache'; +import * as io from '@actions/io'; +import getOS from './get-os'; +import getURL from './get-url'; + +export default async function installer(version: string) { + try { + const extended: string = core.getInput('extended'); + console.log(`Hugo extended: ${extended}`); + + const osName: string = getOS(process.platform); + console.log(`Operating System: ${osName}`); + + const hugoURL: string = getURL(osName, extended, version); + core.debug(`hugoURL: ${hugoURL}`); + + const hugoPath: string = `${process.env.HOME}/bin`; + await io.mkdirP(hugoPath); + core.addPath(hugoPath); + + // Download and extract Hugo binary + const hugoAssets: string = await tc.downloadTool(hugoURL); + let hugoBin: string = ''; + if (osName === 'Windows') { + const hugoExtractedFolder: string = await tc.extractZip( + hugoAssets, + '/tmp' + ); + hugoBin = `${hugoExtractedFolder}/hugo.exe`; + } else { + const hugoExtractedFolder: string = await tc.extractTar( + hugoAssets, + '/tmp' + ); + hugoBin = `${hugoExtractedFolder}/hugo`; + } + await io.mv(hugoBin, hugoPath); + } catch (error) { + core.setFailed(error.message); + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..7e0f9c2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,63 @@ +{ + "compilerOptions": { + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./lib", /* Redirect output structure to the directory. */ + "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + }, + "exclude": ["node_modules", "**/*.test.ts"] +}