Merge pull request #331 from actions/ncalteen-format

Format and add testing/CI
This commit is contained in:
Nick Alteen 2023-09-15 09:37:56 -04:00 committed by GitHub
commit 433d9cdb62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 5947 additions and 4340 deletions

View File

@ -1 +1,4 @@
lib/
dist/
node_modules/
coverage/

View File

@ -1,18 +0,0 @@
{
"env": {
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
}
}

2
.gitattributes vendored
View File

@ -1 +1 @@
dist/** -diff linguist-generated=true
dist/** -diff linguist-generated=true

View File

@ -1,5 +1,5 @@
name: "javascript-action CodeQL config"
name: JavaScript CodeQL Configuration
paths-ignore:
paths-ignore:
- node_modules
- dist

View File

@ -2,10 +2,16 @@ version: 2
updates:
- package-ecosystem: github-actions
directory: /
labels:
- dependabot
- actions
schedule:
interval: daily
- package-ecosystem: npm
directory: /
labels:
- dependabot
- npm
schedule:
interval: daily

50
.github/linters/.eslintrc.yml vendored Normal file
View File

@ -0,0 +1,50 @@
env:
commonjs: true
es6: true
jest: true
node: true
globals:
Atomics: readonly
SharedArrayBuffer: readonly
ignorePatterns:
- '!.*'
- '**/node_modules/.*'
- '**/dist/.*'
- '**/coverage/.*'
- '*.json'
parser: '@babel/eslint-parser'
parserOptions:
ecmaVersion: 2023
sourceType: module
requireConfigFile: false
babelOptions:
babelrc: false
configFile: false
presets:
- jest
plugins:
- jest
extends:
- eslint:recommended
- plugin:github/recommended
- plugin:jest/recommended
rules:
{
'camelcase': 'off',
'eslint-comments/no-use': 'off',
'eslint-comments/no-unused-disable': 'off',
'i18n-text/no-en': 'off',
'import/no-commonjs': 'off',
'import/no-namespace': 'off',
'no-console': 'off',
'no-unused-vars': 'off',
'prettier/prettier': 'error',
'semi': 'off'
}

7
.github/linters/.markdown-lint.yml vendored Normal file
View File

@ -0,0 +1,7 @@
# Unordered list style
MD004:
style: dash
# Ordered list item prefix
MD029:
style: one

10
.github/linters/.yaml-lint.yml vendored Normal file
View File

@ -0,0 +1,10 @@
rules:
document-end: disable
document-start:
level: warning
present: false
line-length:
level: warning
max: 80
allow-non-breakable-words: true
allow-non-breakable-inline-mappings: true

View File

@ -1,8 +1,11 @@
# `dist/index.js` is a special file in Actions.
# When you reference an action with `uses:` in a workflow,
# `index.js` is the code that will run.
# For our project, we generate this file through a build process from other source files.
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
# In JavaScript actions, `dist/index.js` is a special file. When you reference
# an action with `uses:`, `dist/index.js` is the code that will be run. For this
# project, the `dist/index.js` file is generated from other source files through
# the build process. We need to make sure that the checked-in `dist/index.js`
# file matches what is expected from the build.
#
# This workflow will fail if the checked-in `dist/index.js` file does not match
# what is expected from the build.
name: Check dist/
on:
@ -18,33 +21,43 @@ on:
jobs:
check-dist:
name: Check dist/
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
permissions:
contents: read
statuses: write
- name: Set Node.js 16.x
uses: actions/setup-node@v3.6.0
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 16.x
node-version: 20
cache: npm
- name: Install dependencies
- name: Install Dependencies
id: install
run: npm ci
- name: Rebuild the dist/ directory
run: npm run prepare
- name: Build dist/ Directory
id: build
run: npm run bundle
- name: Compare the expected and actual dist/ directories
- name: Compare Expected and Actual Directories
id: diff
run: |
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
git diff
if [ "$(git diff --ignore-space-at-eol --text dist/ | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. See status below:"
git diff --ignore-space-at-eol --text dist/
exit 1
fi
id: diff
# If index.js was different than expected, upload the expected version as an artifact
# If index.js was different than expected, upload the expected version as
# a workflow artifact.
- uses: actions/upload-artifact@v3
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:

60
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,60 @@
name: Continuous Integration
on:
pull_request:
push:
branches:
- main
- "releases/*"
jobs:
test-javascript:
name: JavaScript Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v3
with:
node-version: 20
cache: npm
- name: Install Dependencies
id: npm-ci
run: npm ci
- name: Check Format
id: npm-format-check
run: npm run format:check
- name: Lint
id: npm-lint
run: npm run lint
- name: Test
id: npm-ci-test
run: npm run ci-test
test-action:
name: GitHub Actions Test
runs-on: ubuntu-latest
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Test Local Action
id: test-action
uses: ./
with:
milliseconds: 1000
- name: Print Output
id: output
run: echo "${{ steps.test-action.outputs.time }}"

44
.github/workflows/linter.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: Lint Code Base
on:
pull_request:
branches:
- main
push:
branches-ignore:
- main
jobs:
lint:
name: Lint Code Base
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
statuses: write
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v3
with:
node-version: 20
cache: npm
- name: Install Dependencies
id: install
run: npm ci
- name: Lint Code Base
id: super-linter
uses: super-linter/super-linter/slim@v5
env:
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVASCRIPT_DEFAULT_STYLE: prettier
VALIDATE_JSCPD: false

View File

@ -1,25 +0,0 @@
name: "units-test"
on:
pull_request:
push:
branches:
- main
- 'releases/*'
jobs:
# unit tests
units:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npm test
# test action works running from the graph
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./
with:
milliseconds: 1000

52
.gitignore vendored
View File

@ -1,16 +1,17 @@
node_modules/
# Editors
.vscode/
.idea/
*.iml
# Dependency directory
node_modules
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
@ -23,11 +24,12 @@ lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
@ -39,12 +41,15 @@ bower_components
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Other Dependency directories
# Dependency directories
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
@ -62,6 +67,37 @@ typings/
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# OS metadata
.DS_Store
Thumbs.db
# Ignore built ts files
__tests__/runner/*
# IDE files
.idea
.vscode
*.code-workspace

3
.prettierignore Normal file
View File

@ -0,0 +1,3 @@
dist/
node_modules/
coverage/

16
.prettierrc.json Normal file
View File

@ -0,0 +1,16 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "none",
"bracketSpacing": true,
"bracketSameLine": true,
"arrowParens": "avoid",
"proseWrap": "always",
"htmlWhitespaceSensitivity": "css",
"endOfLine": "lf"
}

View File

@ -1 +1,4 @@
# Repository CODEOWNERS
* @actions/actions-runtime
* @ncalteen

View File

@ -1,4 +1,5 @@
MIT License
The MIT License (MIT)
Copyright (c) 2019 GitHub Actions

229
README.md
View File

@ -1,116 +1,199 @@
# Create a JavaScript Action
<p align="center">
<a href="https://github.com/actions/javascript-action/actions"><img alt="javscript-action status" src="https://github.com/actions/javascript-action/workflows/units-test/badge.svg"></a>
</p>
[![GitHub Super-Linter](https://github.com/actions/javascript-action/actions/workflows/linter.yml/badge.svg)](https://github.com/super-linter/super-linter)
![CI](https://github.com/actions/javascript-action/actions/workflows/ci.yml/badge.svg)
Use this template to bootstrap the creation of a JavaScript action.:rocket:
Use this template to bootstrap the creation of a JavaScript action. :rocket:
This template includes tests, linting, a validation workflow, publishing, and versioning guidance.
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)
If you are new, there's also a simpler introduction in the
[Hello world JavaScript action repository](https://github.com/actions/hello-world-javascript-action).
## Create an action from this template
## Create Your Own Action
Click the `Use this Template` and provide the new repo details for your action
To create your own action, you can use this repository as a template! Just
follow the below instructions:
## Code in Main
1. Click the **Use this template** button at the top of the repository
1. Select **Create a new repository**
1. Select an owner and name for your new repository
1. Click **Create repository**
1. Clone your new repository
Install the dependencies
## Initial Setup
```bash
npm install
```
After you've cloned the repository to your local machine or codespace, you'll
need to perform some initial setup steps before you can develop your action.
Run the tests :heavy_check_mark:
> [!NOTE]
>
> You'll need to have a reasonably modern version of
> [Node.js](https://nodejs.org) handy. If you are using a version manager like
> [`nodenv`](https://github.com/nodenv/nodenv) or
> [`nvm`](https://github.com/nvm-sh/nvm), you can run `nodenv install` in the
> root of your repository to install the version specified in
> [`package.json`](./package.json). Otherwise, 20.x or later should work!
```bash
$ npm test
1. :hammer_and_wrench: Install the dependencies
PASS ./index.test.js
✓ throws invalid number (3ms)
✓ wait 500 ms (504ms)
✓ test runs (95ms)
...
```
```bash
npm install
```
## Change action.yml
1. :building_construction: Package the JavaScript for distribution
The action.yml defines the inputs and output for your action.
```bash
npm run bundle
```
Update the action.yml with your name, description, inputs and outputs for your action.
1. :white_check_mark: Run the tests
See the [documentation](https://help.github.com/en/articles/metadata-syntax-for-github-actions)
```bash
$ npm test
## Change the Code
PASS ./index.test.js
✓ throws invalid number (3ms)
✓ wait 500 ms (504ms)
✓ test runs (95ms)
Most toolkit and CI/CD operations involve async operations so the action is run in an async function.
...
```
```javascript
const core = require('@actions/core');
...
## Update the Action Metadata
async function run() {
try {
...
The [`action.yml`](action.yml) file defines metadata about your action, such as
input(s) and output(s). For details about this file, see
[Metadata syntax for GitHub Actions](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions).
When you copy this repository, update `action.yml` with the name, description,
inputs, and outputs for your action.
## Update the Action Code
The [`src/`](./src/) directory is the heart of your action! This contains the
source code that will be run when your action is invoked. You can replace the
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 `main.js`, you will see that the action is run in an `async` function.
```javascript
const core = require('@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
[documentation](https://github.com/actions/toolkit/blob/master/README.md).
See the [toolkit documentation](https://github.com/actions/toolkit/blob/master/README.md#packages) for the various packages.
So, what are you waiting for? Go ahead and start customizing your action!
## Package for distribution
1. Create a new branch
GitHub Actions will run the entry point from the action.yml. Packaging assembles the code into one file that can be checked in to Git, enabling fast and reliable execution and preventing the need to check in node_modules.
```bash
git checkout -b releases/v1
```
Actions are run from GitHub repos. Packaging the action will create a packaged action in the dist folder.
1. Replace the contents of `src/` with your action code
1. Add tests to `__tests__/` for your source code
1. Format, test, and build the action
Run prepare
```bash
npm run all
```
```bash
npm run prepare
```
> [!WARNING]
>
> This step is important! It will run [`ncc`](https://github.com/vercel/ncc)
> to build the final JavaScript action code with all dependencies included.
> If you do not run this step, your action will not work correctly when it is
> used in a workflow. This step also includes the `--license` option for
> `ncc`, which will create a license file for all of the production node
> modules used in your project.
Since the packaged index.js is run from the dist folder.
1. Commit your changes
```bash
git add dist
```
```bash
git add .
git commit -m "My first action is ready!"
```
## Create a release branch
1. Push them to your repository
Users shouldn't consume the action from master since that would be latest code and actions can break compatibility between major versions.
```bash
git push -u origin releases/v1
```
Checkin to the v1 release branch
```bash
git checkout -b v1
git commit -a -m "v1 release"
```
```bash
git push origin 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.
1. Create a pull request and get feedback on your action
1. Merge the pull request into the `main` branch
Your action is now published! :rocket:
See the [versioning documentation](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)
For information about versioning your action, see
[Versioning](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)
in the GitHub Actions toolkit.
## Validate the Action
You can now validate the action by referencing it in a workflow file. For
example, [`ci.yml`](./.github/workflows/ci.yml) demonstrates how to reference an
action in the same repository.
```yaml
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v3
- name: Test Local Action
id: test-action
uses: ./
with:
milliseconds: 1000
- name: Print Output
id: output
run: echo "${{ steps.test-action.outputs.time }}"
```
For example workflow runs, check out the
[Actions tab](https://github.com/actions/javascript-action/actions)! :rocket:
## Usage
You can now consume the action by referencing the v1 branch
After testing, you can create version tag(s) that developers can use to
reference different stable versions of your action. For more information, see
[Versioning](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)
in the GitHub Actions toolkit.
To include the action in a workflow in another repository, you can use the
`uses` syntax with the `@` symbol to reference a specific branch, tag, or commit
hash.
```yaml
uses: actions/javascript-action@v1
with:
milliseconds: 1000
```
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
See the [actions tab](https://github.com/actions/javascript-action/actions) for runs of this action! :rocket:
- name: Run my Action
id: run-action
uses: actions/javascript-action@v1 # Commit with the `v1` tag
with:
milliseconds: 1000
- name: Print Output
id: output
run: echo "${{ steps.test-action.outputs.time }}"
```

18
__tests__/index.test.js Normal file
View File

@ -0,0 +1,18 @@
/**
* Unit tests for the action's entrypoint, src/index.ts
*/
const { run } = require('../src/main')
// Mock the action's entrypoint
jest.mock('../src/main', () => ({
run: jest.fn()
}))
describe('index', () => {
it('calls run when imported', async () => {
require('../src/index')
expect(run).toHaveBeenCalled()
})
})

100
__tests__/main.test.js Normal file
View File

@ -0,0 +1,100 @@
/**
* 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>`.
*/
const core = require('@actions/core')
const main = require('../src/main')
// Mock the GitHub Actions core library
const debugMock = jest.spyOn(core, 'debug').mockImplementation()
const getInputMock = jest.spyOn(core, 'getInput').mockImplementation()
const setFailedMock = jest.spyOn(core, 'setFailed').mockImplementation()
const setOutputMock = jest.spyOn(core, 'setOutput').mockImplementation()
// 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 => {
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 => {
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'
)
})
it('fails if no input is provided', async () => {
// Set the action's inputs as return values from core.getInput()
getInputMock.mockImplementation(name => {
switch (name) {
case 'milliseconds':
throw new Error('Input required and not supplied: milliseconds')
default:
return ''
}
})
await main.run()
expect(runMock).toHaveReturned()
// Verify that all of the core library functions were called correctly
expect(setFailedMock).toHaveBeenNthCalledWith(
1,
'Input required and not supplied: milliseconds'
)
})
})

24
__tests__/wait.test.js Normal file
View File

@ -0,0 +1,24 @@
/**
* Unit tests for src/wait.ts
*/
const { wait } = require('../src/wait')
const { expect } = require('@jest/globals')
describe('wait.ts', () => {
it('throws an invalid number', async () => {
const input = parseInt('foo', 10)
expect(isNaN(input)).toBe(true)
await expect(wait(input)).rejects.toThrow('milliseconds not a number')
})
it('waits with a valid number', async () => {
const start = new Date()
await wait(500)
const end = new Date()
const delta = Math.abs(end.getTime() - start.getTime())
expect(delta).toBeGreaterThan(450)
})
})

View File

@ -1,13 +1,19 @@
name: 'Wait'
description: 'Wait a designated number of milliseconds'
name: 'The name of your action here'
description: 'Provide a description here'
author: 'Your name or organization here'
# Define your inputs here.
inputs:
milliseconds: # id of input
description: 'number of milliseconds to wait'
milliseconds:
description: 'Your input description here'
required: true
default: '1000'
# Define your outputs here.
outputs:
time: # output will be available to future steps
description: 'The current time after waiting'
time:
description: 'Your output description here'
runs:
using: 'node16'
main: 'dist/index.js'
using: node20
main: dist/index.js

1
badges/coverage.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="106" height="20" role="img" aria-label="Coverage: 100%"><title>Coverage: 100%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="106" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="63" height="20" fill="#555"/><rect x="63" width="43" height="20" fill="#4c1"/><rect width="106" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">Coverage</text><text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">Coverage</text><text aria-hidden="true" x="835" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">100%</text><text x="835" y="140" transform="scale(.1)" fill="#fff" textLength="330">100%</text></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

136
dist/index.js generated vendored
View File

@ -1,7 +1,7 @@
require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 351:
/***/ 241:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
@ -135,7 +135,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;
const command_1 = __nccwpck_require__(351);
const command_1 = __nccwpck_require__(241);
const file_command_1 = __nccwpck_require__(717);
const utils_1 = __nccwpck_require__(278);
const os = __importStar(__nccwpck_require__(37));
@ -558,7 +558,7 @@ class OidcClient {
.catch(error => {
throw new Error(`Failed to get ID Token. \n
Error Code : ${error.statusCode}\n
Error Message: ${error.result.message}`);
Error Message: ${error.message}`);
});
const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value;
if (!id_token) {
@ -1211,6 +1211,19 @@ class HttpClientResponse {
}));
});
}
readBodyBuffer() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
const chunks = [];
this.message.on('data', (chunk) => {
chunks.push(chunk);
});
this.message.on('end', () => {
resolve(Buffer.concat(chunks));
});
}));
});
}
}
exports.HttpClientResponse = HttpClientResponse;
function isHttps(requestUrl) {
@ -1715,7 +1728,13 @@ function getProxyUrl(reqUrl) {
}
})();
if (proxyVar) {
return new URL(proxyVar);
try {
return new URL(proxyVar);
}
catch (_a) {
if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://'))
return new URL(`http://${proxyVar}`);
}
}
else {
return undefined;
@ -1726,6 +1745,10 @@ function checkBypass(reqUrl) {
if (!reqUrl.hostname) {
return false;
}
const reqHost = reqUrl.hostname;
if (isLoopbackAddress(reqHost)) {
return true;
}
const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
if (!noProxy) {
return false;
@ -1751,13 +1774,24 @@ function checkBypass(reqUrl) {
.split(',')
.map(x => x.trim().toUpperCase())
.filter(x => x)) {
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
if (upperNoProxyItem === '*' ||
upperReqHosts.some(x => x === upperNoProxyItem ||
x.endsWith(`.${upperNoProxyItem}`) ||
(upperNoProxyItem.startsWith('.') &&
x.endsWith(`${upperNoProxyItem}`)))) {
return true;
}
}
return false;
}
exports.checkBypass = checkBypass;
function isLoopbackAddress(host) {
const hostLower = host.toLowerCase();
return (hostLower === 'localhost' ||
hostLower.startsWith('127.') ||
hostLower.startsWith('[::1]') ||
hostLower.startsWith('[0:0:0:0:0:0:0:1]'));
}
//# sourceMappingURL=proxy.js.map
/***/ }),
@ -2688,19 +2722,63 @@ exports["default"] = _default;
/***/ }),
/***/ 258:
/***/ 713:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
const core = __nccwpck_require__(186)
const { wait } = __nccwpck_require__(312)
/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
*/
async function run() {
try {
const ms = core.getInput('milliseconds', { required: true })
// 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
core.setFailed(error.message)
}
}
module.exports = {
run
}
/***/ }),
/***/ 312:
/***/ ((module) => {
let wait = function (milliseconds) {
return new Promise((resolve) => {
if (typeof milliseconds !== 'number') {
throw new Error('milliseconds not a number');
/**
* Wait for a number of milliseconds.
*
* @param {number} milliseconds The number of milliseconds to wait.
* @returns {Promise<string>} Resolves with 'done!' after the wait is over.
*/
async function wait(milliseconds) {
return new Promise(resolve => {
if (isNaN(milliseconds)) {
throw new Error('milliseconds not a number')
}
setTimeout(() => resolve("done!"), milliseconds)
});
};
module.exports = wait;
setTimeout(() => resolve('done!'), milliseconds)
})
}
module.exports = { wait }
/***/ }),
@ -2834,31 +2912,15 @@ module.exports = require("util");
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
const core = __nccwpck_require__(186);
const wait = __nccwpck_require__(258);
/**
* The entrypoint for the action.
*/
const { run } = __nccwpck_require__(713)
// most @actions toolkit packages have async methods
async function run() {
try {
const ms = core.getInput('milliseconds');
core.info(`Waiting ${ms} milliseconds ...`);
core.debug((new Date()).toTimeString()); // debug is only output if you set the secret `ACTIONS_RUNNER_DEBUG` to true
await wait(parseInt(ms));
core.info((new Date()).toTimeString());
core.setOutput('time', new Date().toTimeString());
} catch (error) {
core.setFailed(error.message);
}
}
run();
run()
})();
module.exports = __webpack_exports__;
/******/ })()
;
//# sourceMappingURL=index.js.map
;

1
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

1
dist/sourcemap-register.js generated vendored

File diff suppressed because one or more lines are too long

View File

@ -1,21 +0,0 @@
const core = require('@actions/core');
const wait = require('./wait');
// most @actions toolkit packages have async methods
async function run() {
try {
const ms = core.getInput('milliseconds');
core.info(`Waiting ${ms} milliseconds ...`);
core.debug((new Date()).toTimeString()); // debug is only output if you set the secret `ACTIONS_RUNNER_DEBUG` to true
await wait(parseInt(ms));
core.info((new Date()).toTimeString());
core.setOutput('time', new Date().toTimeString());
} catch (error) {
core.setFailed(error.message);
}
}
run();

View File

@ -1,24 +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('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 - start);
expect(delta).toBeGreaterThanOrEqual(500);
});
// shows how the runner will run a javascript action with env / stdout protocol
test('test runs', () => {
process.env['INPUT_MILLISECONDS'] = 100;
const ip = path.join(__dirname, 'index.js');
const result = cp.execSync(`node ${ip}`, {env: process.env}).toString();
console.log(result);
})

9208
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,81 @@
{
"name": "javascript-action",
"version": "1.0.0",
"description": "JavaScript Action Template",
"main": "index.js",
"scripts": {
"lint": "eslint .",
"prepare": "ncc build index.js -o dist --source-map --license licenses.txt",
"test": "jest",
"all": "npm run lint && npm run test && npm run prepare"
},
"description": "GitHub Actions JavaScript Template",
"version": "0.0.0",
"author": "",
"private": true,
"homepage": "https://github.com/actions/javascript-action#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/actions/javascript-action.git"
},
"bugs": {
"url": "https://github.com/actions/javascript-action/issues"
},
"keywords": [
"GitHub",
"Actions",
"JavaScript"
],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/actions/javascript-action/issues"
"exports": {
".": "./dist/index.js"
},
"engines": {
"node": ">=20"
},
"scripts": {
"bundle": "npm run format:write && npm run package",
"ci-test": "jest",
"format:write": "prettier --write **/*.js",
"format:check": "prettier --check **/*.js",
"lint": "npx eslint . -c ./.github/linters/.eslintrc.yml",
"package": "ncc build src/index.js --license licenses.txt",
"package:watch": "npm run package -- --watch",
"test": "(jest && make-coverage-badge --output-path ./badges/coverage.svg) || make-coverage-badge --output-path ./badges/coverage.svg",
"all": "npm run format:write && npm run lint && npm run test && npm run package"
},
"license": "MIT",
"eslintConfig": {
"extends": "./.github/linters/.eslintrc.yml"
},
"jest": {
"verbose": true,
"clearMocks": true,
"testEnvironment": "node",
"moduleFileExtensions": [
"js"
],
"testMatch": [
"**/*.test.js"
],
"testPathIgnorePatterns": [
"/node_modules/",
"/dist/"
],
"coverageReporters": [
"json-summary",
"text",
"lcov"
],
"collectCoverage": true,
"collectCoverageFrom": [
"./src/**"
]
},
"homepage": "https://github.com/actions/javascript-action#readme",
"dependencies": {
"@actions/core": "^1.10.0"
"@actions/core": "^1.10.1"
},
"devDependencies": {
"@vercel/ncc": "^0.36.1",
"eslint": "^8.37.0",
"jest": "^29.5.0"
"@babel/core": "^7.22.17",
"@babel/eslint-parser": "^7.22.15",
"@babel/preset-env": "^7.22.15",
"@vercel/ncc": "^0.38.0",
"babel-preset-jest": "^29.6.3",
"eslint": "^8.49.0",
"eslint-plugin-github": "^4.10.0",
"eslint-plugin-jest": "^27.2.3",
"jest": "^29.7.0",
"make-coverage-badge": "^1.2.0",
"prettier": "^3.0.3"
}
}

6
src/index.js Normal file
View File

@ -0,0 +1,6 @@
/**
* The entrypoint for the action.
*/
const { run } = require('./main')
run()

30
src/main.js Normal file
View File

@ -0,0 +1,30 @@
const core = require('@actions/core')
const { wait } = require('./wait')
/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
*/
async function run() {
try {
const ms = core.getInput('milliseconds', { required: true })
// 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
core.setFailed(error.message)
}
}
module.exports = {
run
}

17
src/wait.js Normal file
View File

@ -0,0 +1,17 @@
/**
* Wait for a number of milliseconds.
*
* @param {number} milliseconds The number of milliseconds to wait.
* @returns {Promise<string>} Resolves with 'done!' after the wait is over.
*/
async function wait(milliseconds) {
return new Promise(resolve => {
if (isNaN(milliseconds)) {
throw new Error('milliseconds not a number')
}
setTimeout(() => resolve('done!'), milliseconds)
})
}
module.exports = { wait }

10
wait.js
View File

@ -1,10 +0,0 @@
let wait = function (milliseconds) {
return new Promise((resolve) => {
if (typeof milliseconds !== 'number') {
throw new Error('milliseconds not a number');
}
setTimeout(() => resolve("done!"), milliseconds)
});
};
module.exports = wait;