1 Commits

Author SHA1 Message Date
Nick Alteen
65ea60d69b Add basic release management 2024-10-31 15:41:23 -04:00
53 changed files with 10232 additions and 37152 deletions

View File

@@ -1,7 +0,0 @@
# See: https://www.checkov.io/1.Welcome/Quick%20Start.html
compact: true
quiet: true
skip-path:
- coverage
- node_modules

View File

@@ -36,6 +36,6 @@
},
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers-community/npm-features/prettier:1": {}
"ghcr.io/devcontainers-contrib/features/prettier:1": {}
}
}

4
.eslintignore Normal file
View File

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

View File

@@ -1,127 +0,0 @@
# Copilot Instructions
This GitHub Action is written in JavaScript and transpiled to a single file.
Both the JavaScript sources and the **generated** JavaScript code are contained
in this repository. The JavaScript sources are contained in the `src` directory
and the code invoked by GitHub Actions is contained in the `dist` directory. A
GitHub Actions workflow checks that the JavaScript code in `dist` is up-to-date.
Therefore, you should not review any changes to the contents of the `dist`
folder and it is expected that the JavaScript code in `dist` closely mirrors the
code it is generated from.
## Repository Structure
| Path | Description |
| -------------------- | -------------------------------------------------------- |
| `__fixtures__/` | Unit Test Fixtures |
| `__tests__/` | Unit Tests |
| `.devcontainer/` | Development Container Configuration |
| `.github/` | GitHub Configuration |
| `.licenses/` | License Information |
| `.vscode/` | Visual Studio Code Configuration |
| `badges/` | Badges for readme |
| `dist/` | Generated JavaScript Code |
| `src/` | JavaScript Source Code |
| `.env.example` | Environment Variables Example for `@github/local-action` |
| `.licensed.yml` | Licensed Configuration |
| `.markdown-lint.yml` | Markdown Linter Configuration |
| `.node-version` | Node.js Version Configuration |
| `.prettierrc.yml` | Prettier Formatter Configuration |
| `.yaml-lint.yml` | YAML Linter Configuration |
| `action.yml` | GitHub Action Metadata |
| `CODEOWNERS` | Code Owners File |
| `eslint.config.mjs` | ESLint Configuration |
| `jest.config.js` | Jest Configuration |
| `LICENSE` | License File |
| `package.json` | NPM Package Configuration |
| `README.md` | Project Documentation |
| `rollup.config.js` | Rollup Bundler Configuration |
## Environment Setup
Install dependencies by running:
```bash
npm install
```
## Testing
Ensure all unit tests pass by running:
```bash
npm run test
```
Unit tests should exist in the `__tests__` directory. They are powered by
`jest`. Fixtures should be placed in the `__fixtures__` directory.
## Bundling
Any time files in the `src` directory are changed, you should run the following
command to bundle the JavaScript code into the `dist` directory:
```bash
npm run bundle
```
## General Coding Guidelines
- Follow standard JavaScript coding conventions and best practices
- Changes should maintain consistency with existing patterns and style
- Document changes clearly and thoroughly, including updates to existing
comments when appropriate
- Do not include basic, unnecessary comments that simply restate what the code
is doing (focus on explaining _why_, not _what_)
- Use consistent error handling patterns throughout the codebase
- Keep functions focused and manageable
- Use descriptive variable and function names that clearly convey their purpose
- Use JSDoc comments to document functions, classes, and complex logic
- After doing any refactoring, ensure to run `npm run test` to ensure that all
tests still pass and coverage requirements are met
- When suggesting code changes, always opt for the most maintainable approach.
Try your best to keep the code clean and follow "Don't Repeat Yourself" (DRY)
principles
- Avoid unnecessary complexity and always consider the long-term maintainability
of the code
- When writing unit tests, try to consider edge cases as well as the main path
of success. This will help ensure that the code is robust and can handle
unexpected inputs or situations
- Use the `@actions/core` package for logging over `console` to ensure
compatibility with GitHub Actions logging features
### Versioning
GitHub Actions are versioned using branch and tag names. Please ensure the
version in the project's `package.json` is updated to reflect the changes made
in the codebase. The version should follow
[Semantic Versioning](https://semver.org/) principles.
## Pull Request Guidelines
When creating a pull request (PR), please ensure that:
- Keep changes focused and minimal (avoid large changes, or consider breaking
them into separate, smaller PRs)
- Formatting checks pass
- Linting checks pass
- Unit tests pass and coverage requirements are met
- The action has been transpiled to JavaScript and the `dist` directory is
up-to-date with the latest changes in the `src` directory
- If necessary, the `README.md` file is updated to reflect any changes in
functionality or usage
The body of the PR should include:
- A summary of the changes
- A special note of any changes to dependencies
- A link to any relevant issues or discussions
- Any additional context that may be helpful for reviewers
## Code Review Guidelines
When performing a code review, please follow these guidelines:
- If there are changes that modify the functionality/usage of the action,
validate that there are changes in the `README.md` file that document the new
or modified functionality

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

View File

@@ -1,13 +1,7 @@
# See: https://github.com/DavidAnson/markdownlint
# Unordered list style
MD004:
style: dash
# Disable line length for tables
MD013:
tables: false
# Ordered list item prefix
MD029:
style: one

View File

@@ -1,5 +1,3 @@
# See: https://yamllint.readthedocs.io/en/stable/
rules:
document-end: disable
document-start:
@@ -10,5 +8,3 @@ rules:
max: 80
allow-non-breakable-words: true
allow-non-breakable-inline-mappings: true
ignore:
- .licenses/

View File

@@ -1,40 +0,0 @@
---
mode: agent
tools: ['changes', 'codebase', 'github']
description: Generate release notes for updates to the repository.
---
# Create Release Notes
You are an expert technical writer tasked with creating release notes for
updates to this repository. Your specific task is to generate release notes that
are clear, concise, and useful for developers and users of the project.
## Guidelines
Ensure you adhere to the following guidelines when creating release notes:
- Use a clear and consistent format for the release notes
- Include a summary of the changes made in the release
- Highlight any new features, improvements, or bugfixes
- If applicable, include instructions for upgrading or migrating to the new
version
- Use technical language that is appropriate for the audience, but avoid jargon
that may not be understood by all users
- Ensure that the release notes are easy to read and navigate
- Include relevant issue or PR numbers where applicable
- Use proper Markdown formatting
- Use code blocks for commands, configuration examples, or code changes
- Use note and warning callouts for important information
## Versioning
GitHub Actions are versioned using branch and tag names. The version in the
project's `package.json` should reflect the changes made in the codebase and
follow [Semantic Versioning](https://semver.org/) principles. Depending on the
nature of the changes, please make sure to adjust the release notes accordingly:
- For **major** changes, include a detailed description of the breaking changes
and how users can adapt to them
- For **minor** changes, highlight new features and improvements
- For **patch** changes, focus on bugfixes and minor improvements

View File

@@ -1,90 +0,0 @@
---
mode: agent
tools: ['codebase', 'github']
description: Generate unit tests for one or more files in the repository.
---
# Create Unit Test(s)
You are an expert software engineer tasked with creating unit tests for the
repository. Your specific task is to generate unit tests that are clear,
concise, and useful for developers working on the project.
## Guidelines
Ensure you adhere to the following guidelines when creating unit tests:
- Use a clear and consistent format for the unit tests
- Include a summary of the functionality being tested
- Use descriptive test names that clearly convey their purpose
- Ensure tests cover both the main path of success and edge cases
- Use proper assertions to validate the expected outcomes
- Use `jest` for writing and running tests
- Place unit tests in the `__tests__` directory
- Use fixtures for any necessary test data, placed in the `__fixtures__`
directory
## Example
Use the following as an example of how to structure your unit tests:
```javascript
/**
* Unit tests for the action's main functionality, src/main.js
*/
import { jest } from '@jest/globals'
import * as core from '../__fixtures__/core.js'
import { wait } from '../__fixtures__/wait.js'
// Mocks should be declared before the module being tested is imported.
jest.unstable_mockModule('@actions/core', () => core)
jest.unstable_mockModule('../src/wait.js', () => ({ wait }))
// The module being tested should be imported dynamically. This ensures that the
// mocks are used in place of any actual dependencies.
const { run } = await import('../src/main.js')
describe('main.js', () => {
beforeEach(() => {
// Set the action's inputs as return values from core.getInput().
core.getInput.mockImplementation(() => '500')
// Mock the wait function so that it does not actually wait.
wait.mockImplementation(() => Promise.resolve('done!'))
})
afterEach(() => {
jest.resetAllMocks()
})
it('Sets the time output', async () => {
await run()
// Verify the time output was set.
expect(core.setOutput).toHaveBeenNthCalledWith(
1,
'time',
// Simple regex to match a time string in the format HH:MM:SS.
expect.stringMatching(/^\d{2}:\d{2}:\d{2}/)
)
})
it('Sets a failed status', async () => {
// Clear the getInput mock and return an invalid value.
core.getInput.mockClear().mockReturnValueOnce('this is not a number')
// Clear the wait mock and return a rejected promise.
wait
.mockClear()
.mockRejectedValueOnce(new Error('milliseconds is not a number'))
await run()
// Verify that the action was marked as failed.
expect(core.setFailed).toHaveBeenNthCalledWith(
1,
'milliseconds is not a number'
)
})
})
```

View File

@@ -9,15 +9,33 @@
# expected from the build.
name: Check Transpiled JavaScript
# This workflow will only run on PRs targeting `main` and direct pushes to
# `main`. It will only run if the listed files/paths are modified (e.g. there is
# no need to run this workflow when documentation files are modified).
on:
pull_request:
branches:
- main
paths:
- src/**
- .node-version
- .prettierrc.json
- package.json
- package-lock.json
- tsconfig.json
push:
branches:
- main
paths:
- src/**
- .node-version
- .prettierrc.json
- package.json
- package-lock.json
- tsconfig.json
permissions:
checks: write
contents: read
jobs:
@@ -28,19 +46,15 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v6
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: npm
- name: Remove dist/ Directory
id: remove-dist
run: npx rimraf ./dist
- name: Install Dependencies
id: install
run: npm ci
@@ -51,7 +65,7 @@ jobs:
# This will fail the workflow if the `dist/` directory is different than
# expected.
- name: Compare Directories
- name: Compare Expected and Actual Directories
id: diff
run: |
if [ ! -d dist/ ]; then
@@ -70,7 +84,7 @@ jobs:
- if: ${{ failure() && steps.diff.outcome == 'failure' }}
name: Upload Artifact
id: upload
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

View File

@@ -1,18 +1,28 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: CodeQL
on:
pull_request:
branches:
- main
push:
branches:
- main
pull_request:
branches:
- main
schedule:
- cron: '31 7 * * 3'
- cron: '24 5 * * 6'
permissions:
actions: read
checks: write
contents: read
security-events: write
@@ -24,26 +34,40 @@ jobs:
strategy:
fail-fast: false
matrix:
language:
- javascript
language: ['javascript']
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v6
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
id: initialize
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@v3
with:
config-file: .github/codeql/codeql-config.yml
languages: ${{ matrix.language }}
source-root: src
config-file: ./.github/codeql/codeql-config.yml
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
id: autobuild
uses: github/codeql-action/autobuild@v4
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
id: analyze
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@v3

View File

@@ -0,0 +1,60 @@
# This workflow creates a new release any time a PR is merged that includes an
# update to the version listed in `package.json`. This ensures that the releases
# are always in sync with the version listed in the package manifest.
name: Continuous Delivery
on:
pull_request:
types:
- closed
branches:
- main
workflow_dispatch:
permissions:
contents: write
jobs:
release:
name: Release Version
runs-on: ubuntu-latest
# Only run this job if the workflow was triggered manually or a
# non-Dependabot PR was merged.
if: |
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true &&
startsWith(github.head_ref, 'dependabot/') == false)
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
# Parse the version from package.json and, if not already present,
# publish a new action version.
- name: Tag
id: tag
uses: issue-ops/semver@v2
with:
manifest-path: package.json
workspace: ${{ github.workspace }}
ref: main
# Always overwrite if the workflow was triggered manually.
overwrite: ${{ github.event_name == 'workflow_dispatch' }}
# Create a release using the tag from the previous step. The release will
# always be created if the workflow was triggered manually, but will only
# be created on PR merge if the tag step ran successfully.
- if: |
github.event_name == 'workflow_dispatch' ||
steps.tag.outcome == 'success'
name: Create Release
id: release
uses: issue-ops/releaser@v2
with:
tag: v${{ steps.tag.outputs.version }}

View File

@@ -1,3 +1,5 @@
# This workflow performs CI tests to ensure that the code reaching `main`
# has been tested and validated.
name: Continuous Integration
on:
@@ -9,6 +11,7 @@ on:
- main
permissions:
checks: write
contents: read
jobs:
@@ -19,11 +22,11 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v6
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: npm
@@ -51,7 +54,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v6
uses: actions/checkout@v4
- name: Test Local Action
id: test-action

View File

@@ -1,74 +0,0 @@
# This workflow checks the statuses of cached dependencies used in this action
# with the help of the Licensed tool. If any licenses are invalid or missing,
# this workflow will fail. See: https://github.com/licensee/licensed
name: Licensed
on:
# Uncomment the below lines to run this workflow on pull requests and pushes
# to the default branch. This is useful for checking licenses before merging
# changes into the default branch.
# pull_request:
# branches:
# - main
# push:
# branches:
# - main
workflow_dispatch:
permissions:
contents: write
jobs:
licensed:
name: Check Licenses
runs-on: ubuntu-latest
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v6
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v6
with:
node-version-file: .node-version
cache: npm
- name: Install Dependencies
id: npm-ci
run: npm ci
- name: Setup Ruby
id: setup-ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ruby
- uses: licensee/setup-licensed@v1.3.2
with:
version: 4.x
github_token: ${{ secrets.GITHUB_TOKEN }}
# If this is a workflow_dispatch event, update the cached licenses.
- if: ${{ github.event_name == 'workflow_dispatch' }}
name: Update Licenses
id: update-licenses
run: licensed cache
# Then, commit the updated licenses to the repository.
- if: ${{ github.event_name == 'workflow_dispatch' }}
name: Commit Licenses
id: commit-licenses
run: |
git config --local user.email "licensed-ci@users.noreply.github.com"
git config --local user.name "licensed-ci"
git add .
git commit -m "Auto-update license files"
git push
# Last, check the status of the cached licenses.
- name: Check Licenses
id: check-licenses
run: licensed status

View File

@@ -1,8 +1,3 @@
# This workflow will lint the entire codebase using the
# `super-linter/super-linter` action.
#
# For more information, see the super-linter repository:
# https://github.com/super-linter/super-linter
name: Lint Codebase
on:
@@ -26,13 +21,13 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v6
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: npm
@@ -43,18 +38,11 @@ jobs:
- name: Lint Codebase
id: super-linter
uses: super-linter/super-linter/slim@v8
uses: super-linter/super-linter/slim@v7
env:
CHECKOV_FILE_NAME: .checkov.yml
DEFAULT_BRANCH: main
FILTER_REGEX_EXCLUDE: dist/**/*
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LINTER_RULES_PATH: .
VALIDATE_JAVASCRIPT_STANDARD: false
VALIDATE_ALL_CODEBASE: true
VALIDATE_BIOME_FORMAT: false
VALIDATE_BIOME_LINT: false
VALIDATE_GITHUB_ACTIONS_ZIZMOR: false
VALIDATE_JAVASCRIPT_ES: false
VALIDATE_JSCPD: false
VALIDATE_TYPESCRIPT_ES: false
VALIDATE_JSON: false

41
.github/workflows/version-check.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
# This workflow checks the version of the action that will be published by the
# current pull request. If the version has already been published, the workflow
# fails in order to prevent PRs from being merged until the version has been
# incremented in the package.json manifest file.
name: Version Check
on:
pull_request:
branches:
- main
env:
MANIFEST_PATH: package.json
permissions:
checks: write
contents: read
pull-requests: write
jobs:
check-version:
name: Version Check
runs-on: ubuntu-latest
# Skips Dependabot PRs
if: ${{ startsWith(github.head_ref, 'dependabot/') == false }}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Check Version
id: check-version
uses: issue-ops/semver@v2
with:
check-only: true
manifest-path: ${{ env.MANIFEST_PATH }}

View File

@@ -1,18 +0,0 @@
# See: https://github.com/licensee/licensed/blob/main/docs/configuration.md
sources:
npm: true
allowed:
- apache-2.0
- bsd-2-clause
- bsd-3-clause
- isc
- mit
- cc0-1.0
- other
ignored:
npm:
# Used by Rollup.js when building in GitHub Actions
- '@rollup/rollup-linux-x64-gnu'

View File

@@ -1,20 +0,0 @@
---
name: "@actions/core"
version: 1.11.1
type: npm
summary: Actions core lib
homepage: https://github.com/actions/toolkit/tree/main/packages/core
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@@ -1,20 +0,0 @@
---
name: "@actions/exec"
version: 1.1.1
type: npm
summary: Actions exec lib
homepage: https://github.com/actions/toolkit/tree/main/packages/exec
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@@ -1,32 +0,0 @@
---
name: "@actions/http-client"
version: 2.2.3
type: npm
summary: Actions Http Client
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
license: other
licenses:
- sources: LICENSE
text: |
Actions Http Client for Node.js
Copyright (c) GitHub, Inc.
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@@ -1,20 +0,0 @@
---
name: "@actions/io"
version: 1.1.3
type: npm
summary: Actions io lib
homepage: https://github.com/actions/toolkit/tree/main/packages/io
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@@ -1,30 +0,0 @@
---
name: "@fastify/busboy"
version: 2.1.1
type: npm
summary: A streaming parser for HTML form data for node.js
homepage:
license: mit
licenses:
- sources: LICENSE
text: |-
Copyright Brian White. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
notices: []

View File

@@ -1,35 +0,0 @@
---
name: tunnel
version: 0.0.6
type: npm
summary: Node HTTP/HTTPS Agents for tunneling proxies
homepage: https://github.com/koichik/node-tunnel/
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2012 Koichi Kobayashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
- sources: README.md
text: Licensed under the [MIT](https://github.com/koichik/node-tunnel/blob/master/LICENSE)
license.
notices: []

View File

@@ -1,34 +0,0 @@
---
name: undici
version: 5.28.5
type: npm
summary: An HTTP/1.1 client, written from scratch for Node.js
homepage: https://undici.nodejs.org
license: mit
licenses:
- sources: LICENSE
text: |
MIT License
Copyright (c) Matteo Collina and Undici contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- sources: README.md
text: MIT
notices: []

View File

@@ -1 +1 @@
24.4.0
20.6.0

View File

@@ -1,5 +1,3 @@
.DS_Store
.licenses/
dist/
node_modules/
coverage/
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,16 +0,0 @@
# See: https://prettier.io/docs/en/configuration
printWidth: 80
tabWidth: 2
useTabs: false
semi: false
singleQuote: true
quoteProps: as-needed
jsxSingleQuote: false
trailingComma: none
bracketSpacing: true
bracketSameLine: true
arrowParens: always
proseWrap: always
htmlWhitespaceSensitivity: css
endOfLine: lf

2
.vscode/launch.json vendored
View File

@@ -7,7 +7,7 @@
"request": "launch",
"runtimeExecutable": "npx",
"cwd": "${workspaceRoot}",
"args": ["@github/local-action", ".", "src/main.js", ".env"],
"args": ["local-action", ".", "src/main.js", ".env"],
"console": "integratedTerminal",
"skipFiles": ["<node_internals>/**", "node_modules/**"]
}

9
.vscode/mcp.json vendored
View File

@@ -1,9 +0,0 @@
{
"servers": {
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"type": "http"
}
},
"inputs": []
}

15
.vscode/settings.json vendored
View File

@@ -1,15 +0,0 @@
{
"github.copilot.chat.reviewSelection.instructions": [
{
"text": "Review the code changes carefully before accepting them."
}
],
"github.copilot.chat.commitMessageGeneration.instructions": [
{
"text": "Use conventional commit message format."
}
],
"github.copilot.chat.pullRequestDescriptionGeneration.instructions": [
{ "text": "Always include a list of key changes." }
]
}

View File

@@ -1,7 +1,3 @@
############################################################################
# Repository CODEOWNERS #
# Order is important! The last matching pattern takes the most precedence. #
############################################################################
# Repository CODEOWNERS
# Default owners, unless a later match takes precedence.
* @actions/actions-oss-maintainers

100
README.md
View File

@@ -1,10 +1,7 @@
# Create a GitHub Action Using JavaScript
# Create a JavaScript Action
[![GitHub Super-Linter](https://github.com/actions/javascript-action/actions/workflows/linter.yml/badge.svg)](https://github.com/actions/javascript-action/actions/workflows/linter.yml)
[![CI](https://github.com/actions/javascript-action/actions/workflows/ci.yml/badge.svg)](https://github.com/actions/javascript-action/actions/workflows/ci.yml)
[![Check dist/](https://github.com/actions/javascript-action/actions/workflows/check-dist.yml/badge.svg)](https://github.com/actions/javascript-action/actions/workflows/check-dist.yml)
[![CodeQL](https://github.com/actions/javascript-action/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/actions/javascript-action/actions/workflows/codeql-analysis.yml)
[![Coverage](./badges/coverage.svg)](./badges/coverage.svg)
[![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:
@@ -39,13 +36,11 @@ need to perform some initial setup steps before you can develop your action.
> [!NOTE]
>
> You'll need to have a reasonably modern version of
> [Node.js](https://nodejs.org) handy (20.x or later should work!). If you are
> using a version manager like [`nodenv`](https://github.com/nodenv/nodenv) or
> [`fnm`](https://github.com/Schniz/fnm), this template has a `.node-version`
> file at the root of the repository that can be used to automatically switch to
> the correct version when you `cd` into the repository. Additionally, this
> `.node-version` file is used by GitHub Actions in any `actions/setup-node`
> actions.
> [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!
1. :hammer_and_wrench: Install the dependencies
@@ -124,10 +119,12 @@ So, what are you waiting for? Go ahead and start customizing your action!
npm run all
```
> This step is important! It will run [`rollup`](https://rollupjs.org/) 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 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.
1. (Optional) Test your action locally
@@ -138,6 +135,7 @@ So, what are you waiting for? Go ahead and start customizing your action!
to a repository.
The `local-action` utility can be run in the following ways:
- Visual Studio Code Debugger
Make sure to review and, if needed, update
@@ -146,8 +144,8 @@ So, what are you waiting for? Go ahead and start customizing your action!
- Terminal/Command Prompt
```bash
# npx @github/local action <action-yaml-path> <entrypoint> <dotenv-file>
npx @github/local-action . src/main.js .env
# npx local action <action-yaml-path> <entrypoint> <dotenv-file>
npx local-action . src/main.js .env
```
You can provide a `.env` file to the `local-action` CLI to set environment
@@ -188,7 +186,7 @@ action in the same repository.
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Test Local Action
id: test-action
@@ -221,58 +219,38 @@ steps:
id: checkout
uses: actions/checkout@v4
- name: Test Local Action
id: test-action
- 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 }}"
run: echo "${{ steps.run-action.outputs.time }}"
```
## Dependency License Management
## Publishing a New Release
This template includes a GitHub Actions workflow,
[`licensed.yml`](./.github/workflows/licensed.yml), that uses
[Licensed](https://github.com/licensee/licensed) to check for dependencies with
missing or non-compliant licenses. This workflow is initially disabled. To
enable the workflow, follow the below steps.
This project includes two workflow files, `continuous-integration.yml` and
`continuous-delivery.yml` that are used to build, test, and publish new releases
of the action.
1. Open [`licensed.yml`](./.github/workflows/licensed.yml)
1. Uncomment the following lines:
The `continuous-integration.yml` workflow is triggered on every push to a pull
request branch. It will run unit tests and add a comment to the pull request
with the test results.
```yaml
# pull_request:
# branches:
# - main
# push:
# branches:
# - main
```
The `continuous-delivery.yml` workflow is triggered when a pull request is
merged to the `main` branch. It will create a new release of the action based on
the version specified in the `version` property of the `package.json` file.
1. Save and commit the changes
The steps to publish a new version are as follows:
Once complete, this workflow will run any time a pull request is created or
changes pushed directly to `main`. If the workflow detects any dependencies with
missing or non-compliant licenses, it will fail the workflow and provide details
on the issue(s) found.
1. Create a feature branch
1. Make changes to the action code
1. Add tests for the changes
1. Update the `version` property in the `package.json` file
1. Commit and push the changes to the feature branch
1. Open a pull request to merge the changes to the `main` branch
### Updating Licenses
Whenever you install or update dependencies, you can use the Licensed CLI to
update the licenses database. To install Licensed, see the project's
[Readme](https://github.com/licensee/licensed?tab=readme-ov-file#installation).
To update the cached licenses, run the following command:
```bash
licensed cache
```
To check the status of cached licenses, run the following command:
```bash
licensed status
```
After the pull request is merged, a new release will be created automatically.

View File

@@ -1,12 +0,0 @@
/**
* This file is used to mock the `@actions/core` module in tests.
*/
import { jest } from '@jest/globals'
export const debug = jest.fn()
export const error = jest.fn()
export const info = jest.fn()
export const getInput = jest.fn()
export const setOutput = jest.fn()
export const setFailed = jest.fn()
export const warning = jest.fn()

View File

@@ -1,3 +0,0 @@
import { jest } from '@jest/globals'
export const wait = jest.fn()

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

@@ -0,0 +1,18 @@
/**
* Unit tests for the action's entrypoint, src/index.js
*/
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()
})
})

View File

@@ -1,62 +1,96 @@
/**
* Unit tests for the action's main functionality, src/main.js
*
* To mock dependencies in ESM, you can create fixtures that export mock
* functions and objects. For example, the core module is mocked in this test,
* so that the actual '@actions/core' module is not imported.
*/
import { jest } from '@jest/globals'
import * as core from '../__fixtures__/core.js'
import { wait } from '../__fixtures__/wait.js'
const core = require('@actions/core')
const main = require('../src/main')
// Mocks should be declared before the module being tested is imported.
jest.unstable_mockModule('@actions/core', () => core)
jest.unstable_mockModule('../src/wait.js', () => ({ wait }))
// 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()
// The module being tested should be imported dynamically. This ensures that the
// mocks are used in place of any actual dependencies.
const { run } = await import('../src/main.js')
// Mock the action's main function
const runMock = jest.spyOn(main, 'run')
describe('main.js', () => {
// Other utilities
const timeRegex = /^\d{2}:\d{2}:\d{2}/
describe('action', () => {
beforeEach(() => {
// Set the action's inputs as return values from core.getInput().
core.getInput.mockImplementation(() => '500')
// Mock the wait function so that it does not actually wait.
wait.mockImplementation(() => Promise.resolve('done!'))
jest.clearAllMocks()
})
afterEach(() => {
jest.resetAllMocks()
})
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 ''
}
})
it('Sets the time output', async () => {
await run()
await main.run()
expect(runMock).toHaveReturned()
// Verify the time output was set.
expect(core.setOutput).toHaveBeenNthCalledWith(
// 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',
// Simple regex to match a time string in the format HH:MM:SS.
expect.stringMatching(/^\d{2}:\d{2}:\d{2}/)
expect.stringMatching(timeRegex)
)
})
it('Sets a failed status', async () => {
// Clear the getInput mock and return an invalid value.
core.getInput.mockClear().mockReturnValueOnce('this is not a number')
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 ''
}
})
// Clear the wait mock and return a rejected promise.
wait
.mockClear()
.mockRejectedValueOnce(new Error('milliseconds is not a number'))
await main.run()
expect(runMock).toHaveReturned()
await run()
// Verify that the action was marked as failed.
expect(core.setFailed).toHaveBeenNthCalledWith(
// Verify that all of the core library functions were called correctly
expect(setFailedMock).toHaveBeenNthCalledWith(
1,
'milliseconds is not a number'
'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'
)
})
})

View File

@@ -1,18 +1,18 @@
/**
* Unit tests for src/wait.js
*/
import { wait } from '../src/wait.js'
const { wait } = require('../src/wait')
const { expect } = require('@jest/globals')
describe('wait.js', () => {
it('Throws an invalid number', async () => {
it('throws an invalid number', async () => {
const input = parseInt('foo', 10)
expect(isNaN(input)).toBe(true)
await expect(wait(input)).rejects.toThrow('milliseconds is not a number')
await expect(wait(input)).rejects.toThrow('milliseconds not a number')
})
it('Waits with a valid number', async () => {
it('waits with a valid number', async () => {
const start = new Date()
await wait(500)
const end = new Date()

View File

@@ -1,24 +1,19 @@
name: The name of your action here
description: Provide a description here
author: Your name or organization here
# Add your action's branding here. This will appear on the GitHub Marketplace.
branding:
icon: heart
color: red
name: 'The name of your action here'
description: 'Provide a description here'
author: 'Your name or organization here'
# Define your inputs here.
inputs:
milliseconds:
description: Your input description here
description: 'Your input description here'
required: true
default: '1000'
# Define your outputs here.
outputs:
time:
description: Your output description here
description: 'Your output description here'
runs:
using: node24
using: node20
main: dist/index.js

View File

@@ -1,6 +0,0 @@
# See: https://github.com/rhysd/actionlint/blob/v1.7.7/docs/config.md
paths:
.github/workflows/**/*.{yml,yaml}:
ignore:
- invalid runner name "node24"

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" 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>
<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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

30872
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

84
dist/licenses.txt generated vendored Normal file
View File

@@ -0,0 +1,84 @@
@actions/core
MIT
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/exec
MIT
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/http-client
MIT
Actions Http Client for Node.js
Copyright (c) GitHub, Inc.
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@actions/io
MIT
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tunnel
MIT
The MIT License (MIT)
Copyright (c) 2012 Koichi Kobayashi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

1
dist/sourcemap-register.js generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,61 +0,0 @@
// See: https://eslint.org/docs/latest/use/configure/configuration-files
import { fixupPluginRules } from '@eslint/compat'
import { FlatCompat } from '@eslint/eslintrc'
import js from '@eslint/js'
import _import from 'eslint-plugin-import'
import jest from 'eslint-plugin-jest'
import prettier from 'eslint-plugin-prettier'
import globals from 'globals'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
})
export default [
{
ignores: ['**/coverage', '**/dist', '**/linter', '**/node_modules']
},
...compat.extends(
'eslint:recommended',
'plugin:jest/recommended',
'plugin:prettier/recommended'
),
{
plugins: {
import: fixupPluginRules(_import),
jest,
prettier
},
languageOptions: {
globals: {
...globals.node,
...globals.jest,
Atomics: 'readonly',
SharedArrayBuffer: 'readonly'
},
ecmaVersion: 2023,
sourceType: 'module'
},
rules: {
camelcase: 'off',
'eslint-comments/no-use': 'off',
'eslint-comments/no-unused-disable': 'off',
'i18n-text/no-en': 'off',
'import/no-namespace': 'off',
'no-console': 'off',
'no-shadow': 'off',
'no-unused-vars': 'off',
'prettier/prettier': 'error'
}
}
]

View File

@@ -1,30 +0,0 @@
// See: https://jestjs.io/docs/configuration
/** @type {import('jest').Config} */
const jestConfig = {
clearMocks: true,
collectCoverage: true,
collectCoverageFrom: ['./src/**'],
coverageDirectory: './coverage',
coveragePathIgnorePatterns: ['/node_modules/', '/dist/'],
coverageReporters: ['json-summary', 'text', 'lcov'],
// Uncomment the below lines if you would like to enforce a coverage threshold
// for your action. This will fail the build if the coverage is below the
// specified thresholds.
// coverageThreshold: {
// global: {
// branches: 100,
// functions: 100,
// lines: 100,
// statements: 100
// }
// },
moduleFileExtensions: ['js'],
reporters: ['default'],
testEnvironment: 'node',
testMatch: ['**/*.test.js'],
testPathIgnorePatterns: ['/dist/', '/node_modules/'],
verbose: true
}
export default jestConfig

15030
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,6 @@
"description": "GitHub Actions JavaScript Template",
"version": "0.0.0",
"author": "",
"type": "module",
"private": true,
"homepage": "https://github.com/actions/javascript-action#readme",
"repository": {
@@ -14,7 +13,9 @@
"url": "https://github.com/actions/javascript-action/issues"
},
"keywords": [
"actions"
"GitHub",
"Actions",
"JavaScript"
],
"exports": {
".": "./dist/index.js"
@@ -24,39 +25,59 @@
},
"scripts": {
"bundle": "npm run format:write && npm run package",
"ci-test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
"ci-test": "npx jest",
"coverage": "npx make-coverage-badge --output-path ./badges/coverage.svg",
"format:write": "npx prettier --write .",
"format:check": "npx prettier --check .",
"lint": "npx eslint .",
"local-action": "npx @github/local-action . src/main.js .env",
"package": "npx rimraf ./dist && npx rollup --config rollup.config.js",
"lint": "npx eslint . -c ./.github/linters/.eslintrc.yml",
"package": "npx ncc build src/index.js -o dist --source-map --license licenses.txt",
"package:watch": "npm run package -- --watch",
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest",
"test": "npx jest",
"all": "npm run format:write && npm run lint && npm run test && npm run coverage && 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/**"
]
},
"dependencies": {
"@actions/core": "^1.11.1"
},
"devDependencies": {
"@eslint/compat": "^1.4.0",
"@github/local-action": "^6.0.2",
"@jest/globals": "^30.2.0",
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-node-resolve": "^16.0.3",
"eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.2.1",
"eslint-plugin-prettier": "^5.5.4",
"jest": "^30.2.0",
"@babel/core": "^7.26.0",
"@babel/eslint-parser": "^7.25.9",
"@babel/preset-env": "^7.26.0",
"@github/local-action": "^2.1.2",
"@vercel/ncc": "^0.38.2",
"babel-preset-jest": "^29.6.3",
"eslint": "^8.57.1",
"eslint-plugin-github": "^5.0.2",
"eslint-plugin-jest": "^28.8.3",
"jest": "^29.7.0",
"make-coverage-badge": "^1.2.0",
"prettier": "^3.7.3",
"prettier-eslint": "^16.4.2",
"rollup": "^4.53.3"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "*"
"prettier": "^3.3.3"
}
}

View File

@@ -1,17 +0,0 @@
// See: https://rollupjs.org/introduction/
import commonjs from '@rollup/plugin-commonjs'
import { nodeResolve } from '@rollup/plugin-node-resolve'
const config = {
input: 'src/index.js',
output: {
esModule: true,
file: 'dist/index.js',
format: 'es',
sourcemap: true
},
plugins: [commonjs(), nodeResolve({ preferBuiltins: true })]
}
export default config

View File

@@ -1,8 +1,6 @@
/**
* The entrypoint for the action. This file simply imports and runs the action's
* main logic.
* The entrypoint for the action.
*/
import { run } from './main.js'
const { run } = require('./main')
/* istanbul ignore next */
run()

View File

@@ -1,14 +1,13 @@
import * as core from '@actions/core'
import { wait } from './wait.js'
const core = require('@actions/core')
const { wait } = require('./wait')
/**
* The main function for the action.
*
* @returns {Promise<void>} Resolves when the action is complete.
*/
export async function run() {
async function run() {
try {
const ms = core.getInput('milliseconds')
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 ...`)
@@ -22,6 +21,10 @@ export async function run() {
core.setOutput('time', new Date().toTimeString())
} catch (error) {
// Fail the workflow run if an error occurs
if (error instanceof Error) core.setFailed(error.message)
core.setFailed(error.message)
}
}
module.exports = {
run
}

View File

@@ -1,13 +1,17 @@
/**
* Waits for a number of milliseconds.
* 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.
*/
export async function wait(milliseconds) {
return new Promise((resolve) => {
if (isNaN(milliseconds)) throw new Error('milliseconds is not a number')
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 }