Cleanup of the template

This commit is contained in:
Michal Dorner 2020-10-01 23:35:59 +02:00
parent c4979203f6
commit e09b207f38
No known key found for this signature in database
GPG key ID: 9EEE04B48DA36786
13 changed files with 1409 additions and 1532 deletions

View file

@ -6,4 +6,4 @@ updates:
directory: '/' directory: '/'
# Check the npm registry for updates every day (weekdays) # Check the npm registry for updates every day (weekdays)
schedule: schedule:
interval: 'daily' interval: 'monthly'

View file

@ -1,24 +1,20 @@
name: 'build-test' name: 'build-test'
on: # rebuild any PRs and main branch changes on:
pull_request: pull_request:
paths-ignore: [ 'README.md' ]
push: push:
branches: paths-ignore: [ 'README.md' ]
- main
- 'releases/*'
jobs: jobs:
build: # make sure build/ci work properly build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: | - run: npm ci
npm install - run: npm run all
- run: |
npm run all test:
test: # make sure the action works on a clean machine without building
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: ./ - uses: ./
with:
milliseconds: 1000

View file

@ -1,7 +1,7 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2018 GitHub, Inc. and contributors Copyright (c) 2020 Michal Dorner and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

104
README.md
View file

@ -1,103 +1,3 @@
<p align="center"> # JUnit Check Report
<a href="https://github.com/actions/typescript-action/actions"><img alt="typescript-action status" src="https://github.com/actions/typescript-action/workflows/build-test/badge.svg"></a>
</p>
# Create a JavaScript Action using TypeScript ** WIP **
Use this template to bootstrap the creation of a TypeScript action.:rocket:
This template includes compilation support, tests, a validation workflow, publishing, and versioning guidance.
If you are new, there's also a simpler introduction. See the [Hello World JavaScript Action](https://github.com/actions/hello-world-javascript-action)
## Create an action from this template
Click the `Use this Template` and provide the new repo details for your action
## Code in Main
Install the dependencies
```bash
$ npm install
```
Build the typescript and package it for distribution
```bash
$ npm run build && npm run package
```
Run the tests :heavy_check_mark:
```bash
$ npm test
PASS ./index.test.js
✓ throws invalid number (3ms)
✓ wait 500 ms (504ms)
✓ test runs (95ms)
...
```
## Change action.yml
The action.yml contains defines the inputs and output for your action.
Update the action.yml with your name, description, inputs and outputs for your action.
See the [documentation](https://help.github.com/en/articles/metadata-syntax-for-github-actions)
## Change the Code
Most toolkit and CI/CD operations involve async operations so the action is run in an async function.
```javascript
import * as core from '@actions/core';
...
async function run() {
try {
...
}
catch (error) {
core.setFailed(error.message);
}
}
run()
```
See the [toolkit documentation](https://github.com/actions/toolkit/blob/master/README.md#packages) for the various packages.
## Publish to a distribution branch
Actions are run from GitHub repos so we will checkin the packed dist folder.
Then run [ncc](https://github.com/zeit/ncc) and push the results:
```bash
$ npm run package
$ git add dist
$ git commit -a -m "prod dependencies"
$ git push origin releases/v1
```
Note: We recommend using the `--license` option for ncc, which will create a license file for all of the production node modules used in your project.
Your action is now published! :rocket:
See the [versioning documentation](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)
## Validate
You can now validate the action by referencing `./` in a workflow in your repo (see [test.yml](.github/workflows/test.yml))
```yaml
uses: ./
with:
milliseconds: 1000
```
See the [actions tab](https://github.com/actions/typescript-action/actions) for runs of this action! :rocket:
## Usage:
After testing you can [create a v1 tag](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md) to reference the stable and latest V1 action

View file

@ -1,27 +1,3 @@
import {wait} from '../src/wait' test('TODO', async () => {
import * as process from 'process' await expect(true).toBeTruthy()
import * as cp from 'child_process'
import * as path from 'path'
test('throws invalid number', async () => {
const input = parseInt('foo', 10)
await expect(wait(input)).rejects.toThrow('milliseconds not a number')
})
test('wait 500 ms', async () => {
const start = new Date()
await wait(500)
const end = new Date()
var delta = Math.abs(end.getTime() - start.getTime())
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, '..', 'lib', 'main.js')
const options: cp.ExecSyncOptions = {
env: process.env
}
console.log(cp.execSync(`node ${ip}`, options).toString())
}) })

View file

@ -1,11 +1,11 @@
name: 'Your name here' name: 'JUnit Check Report'
description: 'Provide a description here' description: 'Presents results of junit test report as Github check run'
author: 'Your name or organization here' author: 'Michal Dorner <dorner.michal@gmail.com>'
inputs: inputs:
milliseconds: # change this token:
required: true description: 'GitHub Access Token'
description: 'input description here' required: false
default: 'default value if applicable' default: ${{ github.token }}
runs: runs:
using: 'node12' using: 'node12'
main: 'dist/index.js' main: 'dist/index.js'

376
dist/index.js generated vendored
View file

@ -1,65 +1,11 @@
require('./sourcemap-register.js');module.exports = require('./sourcemap-register.js');module.exports =
/******/ (function(modules, runtime) { // webpackBootstrap /******/ (() => { // webpackBootstrap
/******/ "use strict"; /******/ "use strict";
/******/ // The module cache /******/ var __webpack_modules__ = ({
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var threw = true;
/******/ try {
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ threw = false;
/******/ } finally {
/******/ if(threw) delete installedModules[moduleId];
/******/ }
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/ // the startup function
/******/ function startup() {
/******/ // Load entry module and return exports
/******/ return __webpack_require__(109);
/******/ };
/******/
/******/ // run startup
/******/ return startup();
/******/ })
/************************************************************************/
/******/ ({
/***/ 87:
/***/ (function(module) {
module.exports = require("os");
/***/ }),
/***/ 109: /***/ 109:
/***/ (function(__unusedmodule, exports, __webpack_require__) { /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
@ -76,7 +22,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
var __importStar = (this && this.__importStar) || function (mod) { var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod; if (mod && mod.__esModule) return mod;
var result = {}; var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod); __setModuleDefault(result, mod);
return result; return result;
}; };
@ -89,18 +35,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__webpack_require__(186)); const core = __importStar(__webpack_require__(186));
const wait_1 = __webpack_require__(817);
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
const ms = core.getInput('milliseconds'); core.info('TODO');
core.debug(`Waiting ${ms} milliseconds ...`); // debug is only output if you set the secret `ACTIONS_RUNNER_DEBUG` to true
core.debug(new Date().toTimeString());
yield wait_1.wait(parseInt(ms, 10));
core.debug(new Date().toTimeString());
core.setOutput('time', new Date().toTimeString());
} }
catch (error) { catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
@ -112,10 +52,94 @@ run();
/***/ }), /***/ }),
/***/ 186: /***/ 351:
/***/ (function(__unusedmodule, exports, __webpack_require__) { /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
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;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const os = __importStar(__webpack_require__(87));
const utils_1 = __webpack_require__(278);
/**
* Commands
*
* Command Format:
* ::name key=value,key=value::message
*
* Examples:
* ::warning::This is the message
* ::set-env name=MY_VAR::some value
*/
function issueCommand(command, properties, message) {
const cmd = new Command(command, properties, message);
process.stdout.write(cmd.toString() + os.EOL);
}
exports.issueCommand = issueCommand;
function issue(name, message = '') {
issueCommand(name, {}, message);
}
exports.issue = issue;
const CMD_STRING = '::';
class Command {
constructor(command, properties, message) {
if (!command) {
command = 'missing.command';
}
this.command = command;
this.properties = properties;
this.message = message;
}
toString() {
let cmdStr = CMD_STRING + this.command;
if (this.properties && Object.keys(this.properties).length > 0) {
cmdStr += ' ';
let first = true;
for (const key in this.properties) {
if (this.properties.hasOwnProperty(key)) {
const val = this.properties[key];
if (val) {
if (first) {
first = false;
}
else {
cmdStr += ',';
}
cmdStr += `${key}=${escapeProperty(val)}`;
}
}
}
}
cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
return cmdStr;
}
}
function escapeData(s) {
return utils_1.toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A');
}
function escapeProperty(s) {
return utils_1.toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A')
.replace(/:/g, '%3A')
.replace(/,/g, '%2C');
}
//# sourceMappingURL=command.js.map
/***/ }),
/***/ 186:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@ -133,8 +157,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
result["default"] = mod; result["default"] = mod;
return result; return result;
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", ({ value: true }));
const command_1 = __webpack_require__(351); const command_1 = __webpack_require__(351);
const file_command_1 = __webpack_require__(717);
const utils_1 = __webpack_require__(278);
const os = __importStar(__webpack_require__(87)); const os = __importStar(__webpack_require__(87));
const path = __importStar(__webpack_require__(622)); const path = __importStar(__webpack_require__(622));
/** /**
@ -161,9 +187,17 @@ var ExitCode;
*/ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function exportVariable(name, val) { function exportVariable(name, val) {
const convertedVal = command_1.toCommandValue(val); const convertedVal = utils_1.toCommandValue(val);
process.env[name] = convertedVal; process.env[name] = convertedVal;
command_1.issueCommand('set-env', { name }, convertedVal); const filePath = process.env['GITHUB_ENV'] || '';
if (filePath) {
const delimiter = '_GitHubActionsFileCommandDelimeter_';
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
file_command_1.issueCommand('ENV', commandValue);
}
else {
command_1.issueCommand('set-env', { name }, convertedVal);
}
} }
exports.exportVariable = exportVariable; exports.exportVariable = exportVariable;
/** /**
@ -179,7 +213,13 @@ exports.setSecret = setSecret;
* @param inputPath * @param inputPath
*/ */
function addPath(inputPath) { function addPath(inputPath) {
command_1.issueCommand('add-path', {}, inputPath); const filePath = process.env['GITHUB_PATH'] || '';
if (filePath) {
file_command_1.issueCommand('PATH', inputPath);
}
else {
command_1.issueCommand('add-path', {}, inputPath);
}
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
} }
exports.addPath = addPath; exports.addPath = addPath;
@ -341,11 +381,11 @@ exports.getState = getState;
/***/ }), /***/ }),
/***/ 351: /***/ 717:
/***/ (function(__unusedmodule, exports, __webpack_require__) { /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
// For internal use, subject to change.
var __importStar = (this && this.__importStar) || function (mod) { var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod; if (mod && mod.__esModule) return mod;
var result = {}; var result = {};
@ -353,61 +393,36 @@ var __importStar = (this && this.__importStar) || function (mod) {
result["default"] = mod; result["default"] = mod;
return result; return result;
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", ({ value: true }));
// We use any as a valid input type
/* eslint-disable @typescript-eslint/no-explicit-any */
const fs = __importStar(__webpack_require__(747));
const os = __importStar(__webpack_require__(87)); const os = __importStar(__webpack_require__(87));
/** const utils_1 = __webpack_require__(278);
* Commands function issueCommand(command, message) {
* const filePath = process.env[`GITHUB_${command}`];
* Command Format: if (!filePath) {
* ::name key=value,key=value::message throw new Error(`Unable to find environment variable for file command ${command}`);
* }
* Examples: if (!fs.existsSync(filePath)) {
* ::warning::This is the message throw new Error(`Missing file at path: ${filePath}`);
* ::set-env name=MY_VAR::some value }
*/ fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {
function issueCommand(command, properties, message) { encoding: 'utf8'
const cmd = new Command(command, properties, message); });
process.stdout.write(cmd.toString() + os.EOL);
} }
exports.issueCommand = issueCommand; exports.issueCommand = issueCommand;
function issue(name, message = '') { //# sourceMappingURL=file-command.js.map
issueCommand(name, {}, message);
} /***/ }),
exports.issue = issue;
const CMD_STRING = '::'; /***/ 278:
class Command { /***/ ((__unused_webpack_module, exports) => {
constructor(command, properties, message) {
if (!command) {
command = 'missing.command'; // We use any as a valid input type
} /* eslint-disable @typescript-eslint/no-explicit-any */
this.command = command; Object.defineProperty(exports, "__esModule", ({ value: true }));
this.properties = properties;
this.message = message;
}
toString() {
let cmdStr = CMD_STRING + this.command;
if (this.properties && Object.keys(this.properties).length > 0) {
cmdStr += ' ';
let first = true;
for (const key in this.properties) {
if (this.properties.hasOwnProperty(key)) {
const val = this.properties[key];
if (val) {
if (first) {
first = false;
}
else {
cmdStr += ',';
}
cmdStr += `${key}=${escapeProperty(val)}`;
}
}
}
}
cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
return cmdStr;
}
}
/** /**
* Sanitizes an input into a string so it can be passed into issueCommand safely * Sanitizes an input into a string so it can be passed into issueCommand safely
* @param input input to sanitize into a string * @param input input to sanitize into a string
@ -422,61 +437,70 @@ function toCommandValue(input) {
return JSON.stringify(input); return JSON.stringify(input);
} }
exports.toCommandValue = toCommandValue; exports.toCommandValue = toCommandValue;
function escapeData(s) { //# sourceMappingURL=utils.js.map
return toCommandValue(s)
.replace(/%/g, '%25') /***/ }),
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A'); /***/ 747:
} /***/ ((module) => {
function escapeProperty(s) {
return toCommandValue(s) module.exports = require("fs");
.replace(/%/g, '%25')
.replace(/\r/g, '%0D') /***/ }),
.replace(/\n/g, '%0A')
.replace(/:/g, '%3A') /***/ 87:
.replace(/,/g, '%2C'); /***/ ((module) => {
}
//# sourceMappingURL=command.js.map module.exports = require("os");
/***/ }), /***/ }),
/***/ 622: /***/ 622:
/***/ (function(module) { /***/ ((module) => {
module.exports = require("path"); module.exports = require("path");
/***/ }),
/***/ 817:
/***/ (function(__unusedmodule, exports) {
"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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.wait = void 0;
function wait(milliseconds) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise(resolve => {
if (isNaN(milliseconds)) {
throw new Error('milliseconds not a number');
}
setTimeout(() => resolve('done!'), milliseconds);
});
});
}
exports.wait = wait;
/***/ }) /***/ })
/******/ }); /******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(__webpack_module_cache__[moduleId]) {
/******/ return __webpack_module_cache__[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var threw = true;
/******/ try {
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ threw = false;
/******/ } finally {
/******/ if(threw) delete __webpack_module_cache__[moduleId];
/******/ }
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat */
/******/
/******/ __webpack_require__.ab = __dirname + "/";/************************************************************************/
/******/ // module exports must be returned from runtime so entry inlining is disabled
/******/ // startup
/******/ // Load entry module and return exports
/******/ return __webpack_require__(109);
/******/ })()
;
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

2362
dist/sourcemap-register.js generated vendored

File diff suppressed because it is too large Load diff

2
package-lock.json generated
View file

@ -1,5 +1,5 @@
{ {
"name": "typescript-action", "name": "junit-check",
"version": "0.0.0", "version": "0.0.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,

View file

@ -1,8 +1,8 @@
{ {
"name": "typescript-action", "name": "junit-check",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"description": "TypeScript template action", "description": "Presents results of junit test report as Github check run",
"main": "lib/main.js", "main": "lib/main.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
@ -15,14 +15,14 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/actions/typescript-action.git" "url": "git+https://github.com/dorny/junit-check.git"
}, },
"keywords": [ "keywords": [
"actions", "actions",
"node", "node",
"setup" "junit"
], ],
"author": "", "author": "Michal Dorner <dorner.michal@gmail.com>",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.2.6" "@actions/core": "^1.2.6"

View file

@ -1,16 +1,8 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import {wait} from './wait'
async function run(): Promise<void> { async function run(): Promise<void> {
try { try {
const ms: string = core.getInput('milliseconds') core.info('TODO')
core.debug(`Waiting ${ms} milliseconds ...`) // debug is only output if you set the secret `ACTIONS_RUNNER_DEBUG` to true
core.debug(new Date().toTimeString())
await wait(parseInt(ms, 10))
core.debug(new Date().toTimeString())
core.setOutput('time', new Date().toTimeString())
} catch (error) { } catch (error) {
core.setFailed(error.message) core.setFailed(error.message)
} }

View file

@ -1,9 +0,0 @@
export async function wait(milliseconds: number): Promise<string> {
return new Promise(resolve => {
if (isNaN(milliseconds)) {
throw new Error('milliseconds not a number')
}
setTimeout(() => resolve('done!'), milliseconds)
})
}