Switch entrypoint and main functionality

This commit is contained in:
Nick Alteen 2023-09-11 15:54:30 -04:00
parent dd289c24c4
commit 03da66625b
6 changed files with 139 additions and 113 deletions

View File

@ -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:
- 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
import * as core from '@actions/core';
...
import * as core from '@actions/core'
//...
async function run() {
try {
...
}
catch (error) {
core.setFailed(error.message);
//...
} catch (error) {
core.setFailed(error.message)
}
}
run()
```
For more information about the GitHub Actions toolkit, see the

View File

@ -1,80 +1,17 @@
/**
* 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 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')
import * as main from '../src/main'
// Mock the action's entrypoint
const runMock = jest.spyOn(index, 'run')
const runMock = jest.spyOn(main, 'run').mockImplementation()
// Other utilities
const timeRegex = /^\d{2}:\d{2}:\d{2}/
describe('index', () => {
it('calls run when imported', async () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('../src/index')
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 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'
)
expect(runMock).toHaveBeenCalled()
})
})

80
__tests__/main.test.ts Normal file
View File

@ -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'
)
})
})

28
dist/index.js generated vendored
View File

@ -2722,7 +2722,7 @@ exports["default"] = _default;
/***/ }),
/***/ 144:
/***/ 399:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@ -2777,8 +2777,6 @@ async function 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 + "/";
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __nccwpck_require__(144);
/******/ module.exports = __webpack_exports__;
/******/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
var 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__;
/******/ })()
;

View File

@ -1,29 +1,7 @@
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.
* The entrypoint for the action.
*/
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)
}
}
import { run } from './main'
// eslint-disable-next-line @typescript-eslint/no-floating-promises
run()

26
src/main.ts Normal file
View File

@ -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)
}
}