diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..19fad63 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,127 @@ +# 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 diff --git a/.github/prompts/create-release-notes.prompt.md b/.github/prompts/create-release-notes.prompt.md new file mode 100644 index 0000000..c7b0fbd --- /dev/null +++ b/.github/prompts/create-release-notes.prompt.md @@ -0,0 +1,40 @@ +--- +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 diff --git a/.github/prompts/unit-test.prompt.md b/.github/prompts/unit-test.prompt.md new file mode 100644 index 0000000..c2e7c9d --- /dev/null +++ b/.github/prompts/unit-test.prompt.md @@ -0,0 +1,90 @@ +--- +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' + ) + }) +}) +``` diff --git a/.github/workflows/check-dist.yml b/.github/workflows/check-dist.yml index 76dc202..283f46f 100644 --- a/.github/workflows/check-dist.yml +++ b/.github/workflows/check-dist.yml @@ -26,12 +26,10 @@ jobs: runs-on: ubuntu-latest steps: - # Checkout the repository. - name: Checkout id: checkout uses: actions/checkout@v4 - # Setup Node.js using the version specified in `.node-version`. - name: Setup Node.js id: setup-node uses: actions/setup-node@v4 @@ -39,12 +37,10 @@ jobs: node-version-file: .node-version cache: npm - # Install dependencies using `npm ci`. - name: Install Dependencies id: install run: npm ci - # Build the `dist/` directory. - name: Build dist/ Directory id: build run: npm run bundle diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25526bf..f517e70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: id: test-action uses: ./ with: - milliseconds: 1000 + milliseconds: 2000 - name: Print Output id: output diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 4823e32..21ea886 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,28 +1,18 @@ -# 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: - push: - branches: - - main pull_request: branches: - main + push: + branches: + - main schedule: - - cron: '24 5 * * 6' + - cron: '31 7 * * 3' permissions: actions: read + checks: write contents: read security-events: write @@ -34,40 +24,26 @@ jobs: strategy: fail-fast: false matrix: - language: ['javascript'] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://git.io/codeql-language-support + language: + - javascript steps: - - name: Checkout repository + - name: Checkout + id: checkout uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL + id: initialize uses: github/codeql-action/init@v3 with: + config-file: .github/codeql/codeql-config.yml languages: ${{ matrix.language }} - 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 + source-root: src - # 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@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@v3 diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 1d6b086..0bb46f4 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -24,14 +24,12 @@ jobs: runs-on: ubuntu-latest steps: - # Checkout the repository. - name: Checkout id: checkout uses: actions/checkout@v4 with: fetch-depth: 0 - # Setup Node.js using the version specified in `.node-version`. - name: Setup Node.js id: setup-node uses: actions/setup-node@v4 @@ -39,12 +37,10 @@ jobs: node-version-file: .node-version cache: npm - # Install dependencies using `npm ci`. - name: Install Dependencies id: install run: npm ci - # Lint the codebase using the `super-linter/super-linter` action. - name: Lint Codebase id: super-linter uses: super-linter/super-linter/slim@v7 diff --git a/.vscode/mcp.json b/.vscode/mcp.json new file mode 100644 index 0000000..7d7a7c0 --- /dev/null +++ b/.vscode/mcp.json @@ -0,0 +1,9 @@ +{ + "servers": { + "github": { + "url": "https://api.githubcopilot.com/mcp/", + "type": "http" + } + }, + "inputs": [] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..390e031 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "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." } + ] +} diff --git a/README.md b/README.md index 18fe363..a5dca94 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ -# Create a JavaScript Action +# Create a GitHub Action Using JavaScript [![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) +[![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) Use this template to bootstrap the creation of a JavaScript action. :rocket: @@ -36,11 +39,13 @@ 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. 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! +> [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. 1. :hammer_and_wrench: Install the dependencies @@ -119,12 +124,10 @@ So, what are you waiting for? Go ahead and start customizing your action! npm run all ``` - > 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. + > 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. 1. (Optional) Test your action locally @@ -135,6 +138,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 @@ -218,15 +222,15 @@ steps: id: checkout uses: actions/checkout@v4 - - name: Run my Action - id: run-action + - name: Test Local Action + id: test-action uses: actions/javascript-action@v1 # Commit with the `v1` tag with: milliseconds: 1000 - name: Print Output id: output - run: echo "${{ steps.run-action.outputs.time }}" + run: echo "${{ steps.test-action.outputs.time }}" ``` ## Dependency License Management diff --git a/package-lock.json b/package-lock.json index a732f2e..8150a01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "eslint-plugin-prettier": "^5.5.1", "jest": "^30.0.4", "make-coverage-badge": "^1.2.0", - "prettier": "^3.6.2", + "prettier": "^3.5.3", "prettier-eslint": "^16.4.2", "rollup": "^4.44.2" }, @@ -9399,9 +9399,9 @@ } }, "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" diff --git a/package.json b/package.json index 6ca9519..31e6526 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "eslint-plugin-prettier": "^5.5.1", "jest": "^30.0.4", "make-coverage-badge": "^1.2.0", - "prettier": "^3.6.2", + "prettier": "^3.5.3", "prettier-eslint": "^16.4.2", "rollup": "^4.44.2" },