Switch entrypoint and main functionality
This commit is contained in:
parent
dd289c24c4
commit
03da66625b
15
README.md
15
README.md
|
@ -79,22 +79,19 @@ contents of this directory with your own code.
|
||||||
There are a few things to keep in mind when writing your action code:
|
There are a few things to keep in mind when writing your action code:
|
||||||
|
|
||||||
- Most GitHub Actions toolkit and CI/CD operations are processed asynchronously.
|
- Most GitHub Actions toolkit and CI/CD operations are processed asynchronously.
|
||||||
In `index.ts`, you will see that the action is run in an `async` function.
|
In `main.ts`, you will see that the action is run in an `async` function.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core'
|
||||||
...
|
//...
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
...
|
//...
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
core.setFailed(error.message)
|
||||||
core.setFailed(error.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information about the GitHub Actions toolkit, see the
|
For more information about the GitHub Actions toolkit, see the
|
||||||
|
|
|
@ -1,80 +1,17 @@
|
||||||
/**
|
/**
|
||||||
* Unit tests for the action's entrypoint, src/index.ts
|
* Unit tests for the action's entrypoint, src/index.ts
|
||||||
*
|
|
||||||
* These should be run as if the action was called from a workflow.
|
|
||||||
* Specifically, the inputs listed in `action.yml` should be set as environment
|
|
||||||
* variables following the pattern `INPUT_<INPUT_NAME>`.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as core from '@actions/core'
|
import * as main from '../src/main'
|
||||||
import * as index from '../src/index'
|
|
||||||
|
|
||||||
// Mock the GitHub Actions core library
|
|
||||||
const debugMock = jest.spyOn(core, 'debug')
|
|
||||||
const getInputMock = jest.spyOn(core, 'getInput')
|
|
||||||
const setFailedMock = jest.spyOn(core, 'setFailed')
|
|
||||||
const setOutputMock = jest.spyOn(core, 'setOutput')
|
|
||||||
|
|
||||||
// Mock the action's entrypoint
|
// Mock the action's entrypoint
|
||||||
const runMock = jest.spyOn(index, 'run')
|
const runMock = jest.spyOn(main, 'run').mockImplementation()
|
||||||
|
|
||||||
// Other utilities
|
describe('index', () => {
|
||||||
const timeRegex = /^\d{2}:\d{2}:\d{2}/
|
it('calls run when imported', async () => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||||
|
require('../src/index')
|
||||||
|
|
||||||
describe('action', () => {
|
expect(runMock).toHaveBeenCalled()
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('sets the time output', async () => {
|
|
||||||
// Set the action's inputs as return values from core.getInput()
|
|
||||||
getInputMock.mockImplementation((name: string): string => {
|
|
||||||
switch (name) {
|
|
||||||
case 'milliseconds':
|
|
||||||
return '500'
|
|
||||||
default:
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await index.run()
|
|
||||||
expect(runMock).toHaveReturned()
|
|
||||||
|
|
||||||
// Verify that all of the core library functions were called correctly
|
|
||||||
expect(debugMock).toHaveBeenNthCalledWith(1, 'Waiting 500 milliseconds ...')
|
|
||||||
expect(debugMock).toHaveBeenNthCalledWith(
|
|
||||||
2,
|
|
||||||
expect.stringMatching(timeRegex)
|
|
||||||
)
|
|
||||||
expect(debugMock).toHaveBeenNthCalledWith(
|
|
||||||
3,
|
|
||||||
expect.stringMatching(timeRegex)
|
|
||||||
)
|
|
||||||
expect(setOutputMock).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
'time',
|
|
||||||
expect.stringMatching(timeRegex)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('sets a failed status', async () => {
|
|
||||||
// Set the action's inputs as return values from core.getInput()
|
|
||||||
getInputMock.mockImplementation((name: string): string => {
|
|
||||||
switch (name) {
|
|
||||||
case 'milliseconds':
|
|
||||||
return 'this is not a number'
|
|
||||||
default:
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await index.run()
|
|
||||||
expect(runMock).toHaveReturned()
|
|
||||||
|
|
||||||
// Verify that all of the core library functions were called correctly
|
|
||||||
expect(setFailedMock).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
'milliseconds not a number'
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* Unit tests for the action's main functionality, src/main.ts
|
||||||
|
*
|
||||||
|
* These should be run as if the action was called from a workflow.
|
||||||
|
* Specifically, the inputs listed in `action.yml` should be set as environment
|
||||||
|
* variables following the pattern `INPUT_<INPUT_NAME>`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as main from '../src/main'
|
||||||
|
|
||||||
|
// Mock the GitHub Actions core library
|
||||||
|
const debugMock = jest.spyOn(core, 'debug')
|
||||||
|
const getInputMock = jest.spyOn(core, 'getInput')
|
||||||
|
const setFailedMock = jest.spyOn(core, 'setFailed')
|
||||||
|
const setOutputMock = jest.spyOn(core, 'setOutput')
|
||||||
|
|
||||||
|
// Mock the action's main function
|
||||||
|
const runMock = jest.spyOn(main, 'run')
|
||||||
|
|
||||||
|
// Other utilities
|
||||||
|
const timeRegex = /^\d{2}:\d{2}:\d{2}/
|
||||||
|
|
||||||
|
describe('action', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets the time output', async () => {
|
||||||
|
// Set the action's inputs as return values from core.getInput()
|
||||||
|
getInputMock.mockImplementation((name: string): string => {
|
||||||
|
switch (name) {
|
||||||
|
case 'milliseconds':
|
||||||
|
return '500'
|
||||||
|
default:
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await main.run()
|
||||||
|
expect(runMock).toHaveReturned()
|
||||||
|
|
||||||
|
// Verify that all of the core library functions were called correctly
|
||||||
|
expect(debugMock).toHaveBeenNthCalledWith(1, 'Waiting 500 milliseconds ...')
|
||||||
|
expect(debugMock).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
expect.stringMatching(timeRegex)
|
||||||
|
)
|
||||||
|
expect(debugMock).toHaveBeenNthCalledWith(
|
||||||
|
3,
|
||||||
|
expect.stringMatching(timeRegex)
|
||||||
|
)
|
||||||
|
expect(setOutputMock).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
'time',
|
||||||
|
expect.stringMatching(timeRegex)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sets a failed status', async () => {
|
||||||
|
// Set the action's inputs as return values from core.getInput()
|
||||||
|
getInputMock.mockImplementation((name: string): string => {
|
||||||
|
switch (name) {
|
||||||
|
case 'milliseconds':
|
||||||
|
return 'this is not a number'
|
||||||
|
default:
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await main.run()
|
||||||
|
expect(runMock).toHaveReturned()
|
||||||
|
|
||||||
|
// Verify that all of the core library functions were called correctly
|
||||||
|
expect(setFailedMock).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
'milliseconds not a number'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
|
@ -2722,7 +2722,7 @@ exports["default"] = _default;
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 144:
|
/***/ 399:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -2777,8 +2777,6 @@ async function run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.run = run;
|
exports.run = run;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
||||||
run();
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
@ -2934,12 +2932,22 @@ module.exports = require("util");
|
||||||
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
|
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
|
||||||
/******/
|
/******/
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/******/
|
var __webpack_exports__ = {};
|
||||||
/******/ // startup
|
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
|
||||||
/******/ // Load entry module and return exports
|
(() => {
|
||||||
/******/ // This entry module is referenced by other modules so it can't be inlined
|
"use strict";
|
||||||
/******/ var __webpack_exports__ = __nccwpck_require__(144);
|
var exports = __webpack_exports__;
|
||||||
/******/ module.exports = __webpack_exports__;
|
|
||||||
/******/
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
/**
|
||||||
|
* The entrypoint for the action.
|
||||||
|
*/
|
||||||
|
const main_1 = __nccwpck_require__(399);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
|
(0, main_1.run)();
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
module.exports = __webpack_exports__;
|
||||||
/******/ })()
|
/******/ })()
|
||||||
;
|
;
|
26
src/index.ts
26
src/index.ts
|
@ -1,29 +1,7 @@
|
||||||
import * as core from '@actions/core'
|
|
||||||
import { wait } from './wait'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main function for the action.
|
* The entrypoint for the action.
|
||||||
* @returns {Promise<void>} Resolves when the action is complete.
|
|
||||||
*/
|
*/
|
||||||
export async function run(): Promise<void> {
|
import { run } from './main'
|
||||||
try {
|
|
||||||
const ms: string = core.getInput('milliseconds')
|
|
||||||
|
|
||||||
// Debug logs are only output if the `ACTIONS_STEP_DEBUG` secret is true
|
|
||||||
core.debug(`Waiting ${ms} milliseconds ...`)
|
|
||||||
|
|
||||||
// Log the current timestamp, wait, then log the new timestamp
|
|
||||||
core.debug(new Date().toTimeString())
|
|
||||||
await wait(parseInt(ms, 10))
|
|
||||||
core.debug(new Date().toTimeString())
|
|
||||||
|
|
||||||
// Set outputs for other workflow steps to use
|
|
||||||
core.setOutput('time', new Date().toTimeString())
|
|
||||||
} catch (error) {
|
|
||||||
// Fail the workflow run if an error occurs
|
|
||||||
if (error instanceof Error) core.setFailed(error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
run()
|
run()
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import { wait } from './wait'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main function for the action.
|
||||||
|
* @returns {Promise<void>} Resolves when the action is complete.
|
||||||
|
*/
|
||||||
|
export async function run(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const ms: string = core.getInput('milliseconds')
|
||||||
|
|
||||||
|
// Debug logs are only output if the `ACTIONS_STEP_DEBUG` secret is true
|
||||||
|
core.debug(`Waiting ${ms} milliseconds ...`)
|
||||||
|
|
||||||
|
// Log the current timestamp, wait, then log the new timestamp
|
||||||
|
core.debug(new Date().toTimeString())
|
||||||
|
await wait(parseInt(ms, 10))
|
||||||
|
core.debug(new Date().toTimeString())
|
||||||
|
|
||||||
|
// Set outputs for other workflow steps to use
|
||||||
|
core.setOutput('time', new Date().toTimeString())
|
||||||
|
} catch (error) {
|
||||||
|
// Fail the workflow run if an error occurs
|
||||||
|
if (error instanceof Error) core.setFailed(error.message)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue