From 3d02cfb49c4a7869b7e6189867c58a41d5f99d7d Mon Sep 17 00:00:00 2001 From: Luis Blanco Date: Tue, 3 Jan 2023 22:55:49 +0400 Subject: [PATCH] Add actionVersion test --- .github/workflows/publish.yml | 40 ++++--- .github/workflows/validate.yml | 3 + utils.d.ts | 194 +++++++++++++++++++-------------- utils/utils.test.js | 13 ++- 4 files changed, 148 insertions(+), 102 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 334507e..b37834b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,16 +1,10 @@ -name: Publish +name: Publish to NPM +defaults: + run: + shell: bash on: - workflow_dispatch: - inputs: - name: - description: 'Release name' - required: true - default: 'Minor Update' - text: - description: 'Patch notes' - required: true - default: Fixed minor issues. + workflow_dispatch jobs: Publish: @@ -20,16 +14,19 @@ jobs: steps: - name: Fetch Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 + with: + persist-credentials: false - name: Install Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: 18.12.1 + cache: 'npm' - - name: Get Npm Version + - name: Get Package Version id: package-version - uses: martinbeentjes/npm-get-version-action@master + run: node -e \"require('./utils').actionVersion()\" >> $GITHUB_OUTPUT - name: Publish run: | @@ -37,12 +34,13 @@ jobs: npm publish --ignore-scripts env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: GitHub Release - uses: actions/create-release@v1 + + - name: Create Release + id: create_release + uses: softprops/action-gh-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: ${{ steps.package-version.outputs.current-version }} - release_name: ${{ github.event.inputs.name }} - body: ${{ github.event.inputs.text }} + tag_name: ${{ steps.package-version.outputs.version }} + name: Release ${{ steps.package-version.outputs.version }} + body: Published at ${{ github.sha }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 09597ed..a99b5ea 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -1,4 +1,7 @@ name: Validate +defaults: + run: + shell: bash on: push: diff --git a/utils.d.ts b/utils.d.ts index 267d194..fe95a76 100644 --- a/utils.d.ts +++ b/utils.d.ts @@ -2,81 +2,115 @@ import type { Writable } from 'stream'; declare module "addon-tools-raub/utils" { /** - * Install binaries - * Downloads and unzips the platform specific binary for the calling package. - * To use it, create a new script for your package, which may as well be named - * **install.js**, with the following content: - * ``` - * 'use strict'; - * const install = require('addon-tools-raub/install'); - * const prefix = 'https://github.com/USER/ADDON-NAME/releases/download'; - * const tag = 'v1.0.0'; - * install(`${prefix}/${tag}`); - * ``` - * * `prefix` - the constant base part of the download url. - * * `tag` - the version-dependent part of the url. - * ``` - * "scripts": { - * "postinstall": "node install" - * }, - * ``` + * Install binaries + * Downloads and unzips the platform specific binary for the calling package. + * To use it, create a new script for your package, which may as well be named + * **install.js**, with the following content: + * ``` + * 'use strict'; + * const install = require('addon-tools-raub/install'); + * const prefix = 'https://github.com/USER/ADDON-NAME/releases/download'; + * const tag = 'v1.0.0'; + * install(`${prefix}/${tag}`); + * ``` + * * `prefix` - the constant base part of the download url. + * * `tag` - the version-dependent part of the url. + * ``` + * "scripts": { + * "postinstall": "node install" + * }, + * ``` */ export const install: (folder: string) => void; /** - * Copy binary - * Copies the addon binary from `src/build/Release` to the platform folder. - * ``` - * declare const cpbin: (name: string) => Promise; - * export default cpbin; - * ``` - * It is useful for development builds. Use it in your **src/package.json**: - * ``` - * "scripts": { - * * "build": "node-gyp rebuild && node -e \"require('addon-tools-raub/cpbin')('ADDON')\"" - * }, - * ``` - * Here ADDON should be replaced with the name of your addon, without `.node` extension. + * Copy binary + * Copies the addon binary from `src/build/Release` to the platform folder. + * ``` + * declare const cpbin: (name: string) => Promise; + * export default cpbin; + * ``` + * It is useful for development builds. Use it in your **src/package.json**: + * ``` + * "scripts": { + * * "build": "node-gyp rebuild && node -e \"require('addon-tools-raub/cpbin')('ADDON')\"" + * }, + * ``` + * Here ADDON should be replaced with the name of your addon, without `.node` extension. */ export const cpbin: (name: string) => Promise; /** - * Download to memory - * Accepts an **URL**, and returns an in-memory file Buffer, - * when the file is loaded. Use for small files, as the whole - * file will be loaded into memory at once. - * - * ``` - * download(srcUrl).then(data => useData(data), err => emit('error', err)); - * ``` - * or - * ``` - * const data = await download(srcUrl); - * useData(data); - * ``` + * Package version for GitHub Actions + * Example of `actionVersion` usage in **Github Actions**: + * + * ``` + * - name: Get Package Version + * id: package-version + * run: node -e \"require('addon-tools-raub/utils').actionVersion()\" >> $GITHUB_OUTPUT + * - name: Create Release + * uses: softprops/action-gh-release@v1 + * with: + * tag_name: ${{ steps.package-version.outputs.version }} + * ``` + */ + export const actionVersion: () => void; + + + /** + * Package version for GitHub Actions + * Example of `actionZip` usage in **Github Actions**: + * + * ``` + * - name: Zip Files + * id: zip-files + * run: node action-zip >> $GITHUB_OUTPUT + * - name: Store Binaries + * uses: softprops/action-gh-release@v1 + * with: + * files: ${{ steps.zip-files.outputs.zip }} + * ``` + */ + export const actionZip: () => void; + + + /** + * Download to memory + * Accepts an **URL**, and returns an in-memory file Buffer, + * when the file is loaded. Use for small files, as the whole + * file will be loaded into memory at once. + * + * ``` + * download(srcUrl).then(data => useData(data), err => emit('error', err)); + * ``` + * or + * ``` + * const data = await download(srcUrl); + * useData(data); + * ``` */ export const download: (url: string) => Promise; /** - * (async) Read a file - * Reads a whole file to string, NOT A Buffer + * (async) Read a file + * Reads a whole file to string, NOT A Buffer */ /** - * WritableBuffer - * A [Writable](https://nodejs.org/api/stream.html#stream_writable_streams) - * stream buffer, that is stored in-memory and can be fully - * obtained when writing was finished. It is equivalent to stream-writing - * a temporary file and then reading it into a `Buffer`. + * WritableBuffer + * A [Writable](https://nodejs.org/api/stream.html#stream_writable_streams) + * stream buffer, that is stored in-memory and can be fully + * obtained when writing was finished. It is equivalent to stream-writing + * a temporary file and then reading it into a `Buffer`. */ export class WritableBuffer extends Writable { constructor(); /** - * Get the downloaded data - * Use `stream.get()` to obtain the data when writing was finished + * Get the downloaded data + * Use `stream.get()` to obtain the data when writing was finished */ get(): Buffer; } @@ -85,97 +119,97 @@ declare module "addon-tools-raub/utils" { export const read: (name: string) => Promise; /** - * (async) Write a file + * (async) Write a file */ export const write: (name: string, text: string) => Promise; /** - * (async) Copy a file + * (async) Copy a file */ export const copy: (src: string, dest: string) => Promise; /** - * (async) Check if a file/folder exists + * (async) Check if a file/folder exists */ export const exists: (name: string) => Promise; /** - * (async) Create an empty folder + * (async) Create an empty folder */ export const mkdir: (name: string) => Promise; /** - * (async) Get status on a file + * (async) Get status on a file */ export const stat: (name: string) => Promise; /** - * (async) Check if the path is a folder + * (async) Check if the path is a folder */ export const isDir: (name: string) => Promise; /** - * (async) Check if the path is a file + * (async) Check if the path is a file */ export const isFile: (name: string) => Promise; /** - * Cut the path one folder up + * Cut the path one folder up */ export const dirUp: (dir: string) => string; /** - * (async) Create a directory - * Like `mkdir -p`, makes sure a directory exists + * (async) Create a directory + * Like `mkdir -p`, makes sure a directory exists */ export const ensuredir: (dir: string) => Promise; /** - * (async) Copy a file - * Copy a file, `dest` folder is created if needed + * (async) Copy a file + * Copy a file, `dest` folder is created if needed */ export const copysafe: (src: string, dest: string) => Promise; /** - * (async) Read a directory - * Get file/folder names of the 1st level + * (async) Read a directory + * Get file/folder names of the 1st level */ export const readdir: (src: string, dest: string) => Promise>; /** - * (async) List subdirectories - * Get folder paths (concatenated with input) of the 1st level + * (async) List subdirectories + * Get folder paths (concatenated with input) of the 1st level */ export const subdirs: (name: string) => Promise>; /** - * (async) List nested files - * Get file paths (concatenated with input) of the 1st level + * (async) List nested files + * Get file paths (concatenated with input) of the 1st level */ export const subfiles: (name: string) => Promise>; /** - * (async) Get all nested files recursively - * Folder paths are omitted by default. - * Order is: shallow-to-deep, each subdirectory lists dirs-then-files. + * (async) Get all nested files recursively + * Folder paths are omitted by default. + * Order is: shallow-to-deep, each subdirectory lists dirs-then-files. */ export const traverse: (name: string, showDirs?: boolean) => Promise>; /** - * (async) Copy a directory - * Copy a folder with all the contained files + * (async) Copy a directory + * Copy a folder with all the contained files */ export const copyall: (src: string, dest: string) => Promise; /** - * (async) Remove a directory - * Like `rm -rf`, removes everything recursively + * (async) Remove a directory + * Like `rm -rf`, removes everything recursively */ export const rmdir: (name: string) => Promise; /** - * (async) Remove a file - * Must be a file, not a folder. Just `fs.unlink`. + * (async) Remove a file + * Must be a file, not a folder. Just `fs.unlink`. */ export const rm: (name: string) => Promise; } diff --git a/utils/utils.test.js b/utils/utils.test.js index 17ff106..57ba335 100644 --- a/utils/utils.test.js +++ b/utils/utils.test.js @@ -1,6 +1,10 @@ 'use strict'; +const util = require('node:util'); +const exec = util.promisify(require('node:child_process').exec); + const utils = require('.'); +const packageJson = require('../package.json'); describe('utils.js', () => { @@ -12,8 +16,15 @@ describe('utils.js', () => { ]; methods.forEach((name) => { - it('is a function', () => { + it(`exports the "${name}" function`, () => { expect(typeof utils[name]).toBe('function'); }); }); + + describe('actionVersion', () => { + it('logs package version', async () => { + const { stdout } = await exec('node -e "require(\'./utils\').actionVersion()"'); + expect(stdout).toBe(`version=${packageJson.version}`); + }); + }); });