From 42ae1a5ee3656aa0a796f4cf3f84e26df24ce1c9 Mon Sep 17 00:00:00 2001 From: Nick Alteen Date: Fri, 11 Jul 2025 13:29:25 -0400 Subject: [PATCH] feat: add Copilot instructions and guidelines for unit tests and release notes --- .github/copilot-instructions.md | 133 ++++++++++++++++++ .../prompts/create-release-notes.prompt.md | 34 +++++ .github/prompts/unit-test.prompt.md | 84 +++++++++++ .vscode/mcp.json | 9 ++ .vscode/settings.json | 15 ++ 5 files changed, 275 insertions(+) create mode 100644 .github/copilot-instructions.md create mode 100644 .github/prompts/create-release-notes.prompt.md create mode 100644 .github/prompts/unit-test.prompt.md create mode 100644 .vscode/mcp.json create mode 100644 .vscode/settings.json diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..a75f466 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,133 @@ +# Copilot Instructions + +This GitHub Action is written in TypeScript and transpiled to JavaScript. The +transpiled JavaScript is invoked from within a Docker container. Both the +TypeScript sources and the **generated** JavaScript code are contained in this +repository. The TypeScript sources are contained in the `src` directory and the +JavaScript code 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 TypeScript 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/` | VSCode Configuration | +| `badges/` | Badges for README | +| `dist/` | Generated JavaScript Code | +| `src/` | TypeScript Source Code | +| `.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 | +| `Dockerfile` | Dockerfile for the Action | +| `eslint.config.mjs` | ESLint Configuration | +| `jest.config.js` | Jest Configuration | +| `LICENSE` | License File | +| `package.json` | NPM Package Configuration | +| `README.md` | Project Documentation | +| `rollup.config.ts` | Rollup Bundler Configuration | +| `tsconfig.base.json` | Base TypeScript Configuration | +| `tsconfig.eslint.json` | TypeScript Configuration for ESLint | +| `tsconfig.json` | TypeScript 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 TypeScript code into JavaScript: + +```bash +npm run bundle +``` + +## General Coding Guidelines + +- Follow standard TypeScript and 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 +- Use TypeScript's type system to ensure type safety and clarity +- 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..c2f1893 --- /dev/null +++ b/.github/prompts/create-release-notes.prompt.md @@ -0,0 +1,34 @@ +# 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 bug fixes +- 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 bug fixes 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..7e2cd35 --- /dev/null +++ b/.github/prompts/unit-test.prompt.md @@ -0,0 +1,84 @@ +# 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: + +```typescript +/** + * Unit tests for the action's main functionality, src/main.ts + */ +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.ts', () => { + 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/.vscode/mcp.json b/.vscode/mcp.json new file mode 100644 index 0000000..2d34de4 --- /dev/null +++ b/.vscode/mcp.json @@ -0,0 +1,9 @@ +{ + "servers": { + "github": { + "url": "https://api.githubcopilot.com/mcp/", + "type": "http" + } + }, + "inputs": [] +} \ No newline at end of file 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." } + ] +}