diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..9c13c11d9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ +## Choose a PR Template + +Please select the appropriate PR template for your contribution: + +- πŸ†• [New Module](?template=new_module.md) - Adding a new module to the registry +- πŸ› [Bug Fix](?template=bug_fix.md) - Fixing an existing issue +- ✨ [Feature](?template=feature.md) - Adding new functionality to a module +- πŸ“ [Documentation](?template=documentation.md) - Improving docs only + +--- + +If you've already started your PR, add `?template=TEMPLATE_NAME.md` to your URL. + +### Quick Checklist + +- [ ] Tests pass (`bun test`) +- [ ] Code formatted (`bun run fmt`) +- [ ] Following contribution guidelines diff --git a/.github/PULL_REQUEST_TEMPLATE/bug_fix.md b/.github/PULL_REQUEST_TEMPLATE/bug_fix.md new file mode 100644 index 000000000..c9a53217a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/bug_fix.md @@ -0,0 +1,22 @@ +## Bug Fix: [Brief Description] + +**Module:** `registry/[namespace]/modules/[module-name]` +**Version:** `v1.2.3` β†’ `v1.2.4` + +### Problem + + + +### Solution + + + +### Testing + +- [ ] Tests pass (`bun test`) +- [ ] Code formatted (`bun run fmt`) +- [ ] Fix verified locally + +### Related Issue + + diff --git a/.github/PULL_REQUEST_TEMPLATE/documentation.md b/.github/PULL_REQUEST_TEMPLATE/documentation.md new file mode 100644 index 000000000..32031022b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/documentation.md @@ -0,0 +1,23 @@ +## Documentation Update + +### Description + + + +### Changes + + + +- +- + +### Checklist + +- [ ] README validation passes (if applicable) +- [ ] Code examples tested +- [ ] Links verified +- [ ] Formatting consistent + +### Context + + diff --git a/.github/PULL_REQUEST_TEMPLATE/feature.md b/.github/PULL_REQUEST_TEMPLATE/feature.md new file mode 100644 index 000000000..b666cc991 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/feature.md @@ -0,0 +1,32 @@ +## Feature: [Brief Description] + +**Module:** `registry/[namespace]/modules/[module-name]` +**Version:** `v1.2.3` β†’ `v1.3.0` (or `v2.0.0` for breaking changes) + +### Description + + + +### Changes + + + +- +- + +### Breaking Changes + + + +- None / _Remove if not applicable_ + +### Testing + +- [ ] Tests pass (`bun test`) +- [ ] Code formatted (`bun run fmt`) +- [ ] New tests added for feature +- [ ] Backward compatibility maintained + +### Documentation + + diff --git a/.github/PULL_REQUEST_TEMPLATE/new_module.md b/.github/PULL_REQUEST_TEMPLATE/new_module.md new file mode 100644 index 000000000..dd0f84276 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/new_module.md @@ -0,0 +1,25 @@ +## New Module: [Module Name] + +**Module Path:** `registry/[namespace]/modules/[module-name]` +**Initial Version:** `v1.0.0` + +### Description + + + +### Checklist + +- [ ] All required files included (`main.tf`, `main.test.ts`, `README.md`) +- [ ] Tests pass (`bun test`) +- [ ] Code formatted (`bun run fmt`) +- [ ] README has proper frontmatter +- [ ] Icon path is valid +- [ ] Namespace has avatar (if first-time contributor) + +### Testing + + + +### Additional Notes + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f49b6010e..a0e8f6332 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,294 +1,297 @@ -# Contributing +# Contributing to the Coder Registry -## Getting started +Welcome! This guide covers how to contribute to the Coder Registry, whether you're creating a new module or improving an existing one. -This repo uses two main runtimes to verify the correctness of a module/template before it is published: +## What is the Coder Registry? -- [Bun](https://bun.sh/) – Used to run tests for each module/template to validate overall functionality and correctness of Terraform output -- [Go](https://go.dev/) – Used to validate all README files in the directory. The README content is used to populate [the Registry website](https://registry.coder.com). +The Coder Registry is a collection of Terraform modules that extend Coder workspaces with development tools like VS Code, Cursor, JetBrains IDEs, and more. -### Installing Bun +## Types of Contributions -To install Bun, you can run this command on Linux/MacOS: +- **[New Modules](#creating-a-new-module)** - Add support for a new tool or functionality +- **[Existing Modules](#contributing-to-existing-modules)** - Fix bugs, add features, or improve documentation +- **[Bug Reports](#reporting-issues)** - Report problems or request features -```shell -curl -fsSL https://bun.sh/install | bash -``` +## Setup -Or this command on Windows: +### Prerequisites -```shell -powershell -c "irm bun.sh/install.ps1 | iex" -``` +- Basic Terraform knowledge (for module development) +- Terraform installed ([installation guide](https://developer.hashicorp.com/terraform/install)) +- Docker (for running tests) -Follow the instructions to ensure that Bun is available globally. Once Bun is installed, install all necessary dependencies from the root of the repo: +### Install Dependencies -Via NPM: +Install Bun: -```shell -npm i +```bash +curl -fsSL https://bun.sh/install | bash ``` -Via PNPM: +Install project dependencies: -```shell -pnpm i +```bash +bun install ``` -This repo does not support Yarn. - -### Installing Go (optional) - -This step can be skipped if you are not working on any of the README validation logic. The validation will still run as part of CI. +### Understanding Namespaces -[Navigate to the official Go Installation page](https://go.dev/doc/install), and install the correct version for your operating system. +All modules are organized under `/registry/[namespace]/modules/`. Each contributor gets their own namespace (e.g., `/registry/your-username/modules/`). If a namespace is taken, choose a different unique namespace, but you can still use any display name on the Registry website. -Once Go has been installed, verify the installation via: +### Images and Icons -```shell -go version -``` - -## Namespaces +- **Namespace avatars**: Must be named `avatar.png` or `avatar.svg` in `/registry/[namespace]/.images/` +- **Module screenshots/demos**: Use `/registry/[namespace]/.images/` for module-specific images +- **Module icons**: Use the shared `/.icons/` directory at the root for module icons -All Coder resources are scoped to namespaces placed at the top level of the `/registry` directory. Any modules or templates must be placed inside a namespace to be accepted as a contribution. For example, all modules created by CoderEmployeeBob would be placed under `/registry/coderemployeebob/modules`, with a subdirectory for each individual module the user has published. +--- -If a namespace is already taken, you will need to create a different, unique namespace, but will still be able to choose any display name. (The display name is shown in the Registry website. More info below.) +## Creating a New Module -### Namespace (contributor profile) README files +### 1. Create Your Namespace (First Time Only) -More information about contributor profile README files can be found below. +If you're a new contributor, create your namespace: -### Images +```bash +mkdir -p registry/[your-username] +mkdir -p registry/[your-username]/.images +``` -Any images needed for either the main namespace directory or a module/template can be placed in a relative `/images` directory at the top of the namespace directory. (e.g., CoderEmployeeBob can have a `/registry/coderemployeebob/images` directory, that can be referenced by the main README file, as well as a README file in `/registry/coderemployeebob/modules/custom_module/README.md`.) This is to minimize the risk of file name conflicts between different users as they add images to help illustrate parts of their README files. +#### Add Your Avatar -## Coder modules +Every namespace must have an avatar. We recommend using your GitHub avatar: -### Adding a new module +1. Download your GitHub avatar from `https://github.com/[your-username].png` +2. Save it as `avatar.png` in `registry/[your-username]/.images/` +3. This gives you a properly sized, square image that's already familiar to the community -> [!WARNING] -> These instructions cannot be followed just yet; the script referenced will be made available shortly. Contributors looking to add modules early will need to create all directories manually. +The avatar must be: -Once Bun (and possibly Go) have been installed, clone the Coder Registry repository. From there, you can run this script to make it easier to start contributing a new module or template: +- Named exactly `avatar.png` or `avatar.svg` +- Square image (recommended: 400x400px minimum) +- Supported formats: `.png` or `.svg` only -```shell -./new.sh USER_NAMESPACE/NAME_OF_NEW_MODULE -``` +#### Create Your Namespace README -You can also create a module file manually by creating the necessary files and directories. +Create `registry/[your-username]/README.md`: -### The composition of a Coder module +```markdown +--- +display_name: "Your Name" +bio: "Brief description of who you are and what you do" +avatar_url: "./.images/avatar.png" +github: "your-username" +linkedin: "https://www.linkedin.com/in/your-username" # Optional +website: "https://yourwebsite.com" # Optional +support_email: "you@example.com" # Optional +status: "community" +--- -Each Coder Module must contain the following files: +# Your Name -- A `main.tf` file that defines the main Terraform-based functionality -- A `main.test.ts` file that is used to validate that the module works as expected -- A `README.md` file containing required information (listed below) +Brief description of who you are and what you do. +``` -You are free to include any additional files in the module, as needed by the module. For example, the [Windows RDP module](https://github.com/coder/registry/tree/main/registry/coder/modules/windows-rdp) contains additional files for injecting specific functionality into a Coder Workspace. +> **Note**: The `avatar_url` must point to `./.images/avatar.png` or `./.images/avatar.svg`. -> [!NOTE] -> Some legacy modules do not have test files defined just yet. This will be addressed soon. +### 2. Generate Module Files -### The `main.tf` file +```bash +./scripts/new_module.sh [your-username]/[module-name] +cd registry/[your-username]/modules/[module-name] +``` -This file defines all core Terraform functionality, to be mixed into your Coder workspaces. More information about [Coder's use of Terraform can be found here](https://coder.com/docs/admin/templates/extending-templates/modules), and [general information about the Terraform language can be found in the official documentation](https://developer.hashicorp.com/terraform/docs). +This script generates: -### The structure of a module README +- `main.tf` - Terraform configuration template +- `README.md` - Documentation template with frontmatter +- `run.sh` - Script for module execution (can be deleted if not required) -Validation criteria for module README files is listed below. +### 3. Build Your Module -### Testing a Module +1. **Edit `main.tf`** to implement your module's functionality +2. **Update `README.md`** with: + - Accurate description and usage examples + - Correct icon path (usually `../../../../.icons/your-icon.svg`) + - Proper tags that describe your module +3. **Create `main.test.ts`** to test your module +4. **Add any scripts** or additional files your module needs -> [!IMPORTANT] -> It is the responsibility of the module author to implement tests for every new module they wish to contribute. It is expected the author has tested the module locally before opening a PR. Feel free to reference existing test files to get an idea for how to set them up. +### 4. Test and Submit -All general-purpose test helpers for validating Terraform can be found in the top-level `/testing` directory. The helpers run `terraform apply` on modules that use variables, testing the script output against containers. +```bash +# Test your module +bun test -t 'module-name' -When writing a test file, you can import the test utilities via the `~test` import alias: +# Format code +bun fmt -```ts -// This works regardless of how deeply-nested your test file is in the file -// structure -import { - runTerraformApply, - runTerraformInit, - testRequiredVariables, -} from "~test"; +# Commit and create PR +git add . +git commit -m "Add [module-name] module" +git push origin your-branch ``` -> [!NOTE] -> The testing suite must be able to run docker containers with the `--network=host` flag. This typically requires running the tests on Linux as this flag does not apply to Docker Desktop for MacOS or Windows. MacOS users can work around this by using something like [colima](https://github.com/abiosoft/colima) or [Orbstack](https://orbstack.dev/) instead of Docker Desktop. +> **Important**: It is your responsibility to implement tests for every new module. Test your module locally before opening a PR. The testing suite requires Docker containers with the `--network=host` flag, which typically requires running tests on Linux (this flag doesn't work with Docker Desktop on macOS/Windows). macOS users can use [Colima](https://github.com/abiosoft/colima) or [OrbStack](https://orbstack.dev/) instead of Docker Desktop. -#### Running tests +--- -You can run all tests by running this command from the root of the Registry directory: +## Contributing to Existing Modules -```shell -bun test -``` - -Note that running _all_ tests can take some time, so you likely don't want to be running this command as part of your core development loop. +### 1. Find the Module -To run specific tests, you can use the `-t` flag, which accepts a filepath regex: - -```shell -bun test -t '' +```bash +find registry -name "*[module-name]*" -type d ``` -To ensure that the module runs predictably in local development, you can update the Terraform source as follows: - -```tf -module "example" { - # You may need to remove the 'version' field, it is incompatible with some sources. - source = "git::https://github.com//.git//?ref=" -} -``` +### 2. Make Your Changes -## Updating README files +**For bug fixes:** -This repo uses Go to validate each README file. If you are working with the README files at all (i.e., creating them, modifying them), it is strongly recommended that you install Go (installation instructions mentioned above), so that the files can be validated locally. +- Reproduce the issue +- Fix the code in `main.tf` +- Add/update tests +- Update documentation if needed -### Validating all README files +**For new features:** -To validate all README files throughout the entire repo, you can run the following: +- Add new variables with sensible defaults +- Implement the feature +- Add tests for new functionality +- Update README with new variables -```shell -go build ./cmd/readmevalidation && ./readmevalidation -``` +**For documentation:** -The resulting binary is already part of the `.gitignore` file, but you can remove it with: +- Fix typos and unclear explanations +- Add missing variable documentation +- Improve usage examples -```shell -rm ./readmevalidation -``` +### 3. Test Your Changes -### README validation criteria +```bash +# Test a specific module +bun test -t 'module-name' -The following criteria exists for two reasons: +# Test all modules +bun test +``` -1. Content accessibility -2. Having content be designed in a way that's easy for the Registry site build step to use +### 4. Maintain Backward Compatibility -#### General README requirements +- New variables should have default values +- Don't break existing functionality +- Test that minimal configurations still work -- There must be a frontmatter section. -- There must be exactly one h1 header, and it must be at the very top, directly below the frontmatter. -- The README body (if it exists) must start with an h1 header. No other content (including GitHub-Flavored Markdown alerts) is allowed to be placed above it. -- When increasing the level of a header, the header's level must be incremented by one each time. -- Any `.hcl` code snippets must be labeled as `.tf` snippets instead +--- - ````txt - ```tf - Content - ``` - ```` +## Submitting Changes -#### Namespace (contributor profile) criteria +1. **Fork and branch:** -In addition to the general criteria, all README files must have the following: + ```bash + git checkout -b fix/module-name-issue + ``` -- Frontmatter metadata with support for the following fields: +2. **Commit with clear messages:** - - `display_name` (required string) – The name to use when displaying your user profile in the Coder Registry site. - - `bio` (optional string) – A short description of who you are. - - `github` (optional string) – Your GitHub handle. - - `avatar_url` (optional string) – A relative/absolute URL pointing to your avatar for the Registry site. It is strongly recommended that you commit avatar images to this repo and reference them via a relative URL. - - `linkedin` (optional string) – A URL pointing to your LinkedIn page. - - `support_email` (optional string) – An email for users to reach you at if they need help with a published module/template. - - `status` (string union) – If defined, this must be one of `"community"`, `"partner"`, or `"official"`. `"community"` should be used for the majority of external contributions. `"partner"` is for companies who have a formal business partnership with Coder. `"official"` should be used only by Coder employees. + ```bash + git commit -m "Fix version parsing in module-name" + ``` -- The README body (the content that goes directly below the frontmatter) is allowed to be empty, but if it isn't, it must follow all the rules above. +3. **Open PR with:** + - Clear title describing the change + - What you changed and why + - Any breaking changes -You are free to customize the body of a contributor profile however you like, adding any number of images or information. Its content will never be rendered in the Registry website. +### Using PR Templates -Additional information can be placed in the README file below the content listed above, using any number of headers. +We have different PR templates for different types of contributions. GitHub will show you options to choose from, or you can manually select: -Additional image/video assets can be placed in the same user namespace directory where that user's main content lives. +- **New Module**: Use `?template=new_module.md` +- **Bug Fix**: Use `?template=bug_fix.md` +- **Feature**: Use `?template=feature.md` +- **Documentation**: Use `?template=documentation.md` -#### Module criteria +Example: `https://github.com/coder/registry/compare/main...your-branch?template=new_module.md` -In addition to the general criteria, all README files must have the following: +--- -- Frontmatter that describes metadata for the module: - - `display_name` (required string) – This is the name displayed on the Coder Registry website - - `description` (required string) – A short description of the module, which is displayed on the Registry website - - `icon` (required string) – A relative/absolute URL pointing to the icon to display for the module in the Coder Registry website. - - `verified` (optional boolean) – Indicates whether the module has been officially verified by Coder. Please do not set this without approval from a Coder employee. - - `tags` (required string array) – A list of metadata tags to describe the module. Used in the Registry site for search and navigation functionality. - - `maintainer_github` (deprecated string) – The name of the creator of the module. This field exists for backwards compatibility with previous versions of the Registry, but going forward, the value will be inferred from the namespace directory. - - `partner_github` (deprecated string) - The name of any additional creators for a module. This field exists for backwards compatibility with previous versions of the Registry, but should not ever be used going forward. -- The following content directly under the h1 header (without another header between them): +## Requirements - - A description of what the module does - - A Terraform snippet for letting other users import the functionality +### Every Module Must Have - ```tf - module "cursor" { - count = data.coder_workspace.me.start_count - source = "registry.coder.com/coder/cursor/coder" - version = "1.0.19" - agent_id = coder_agent.example.id - } - ``` +- `main.tf` - Terraform code +- `main.test.ts` - Working tests +- `README.md` - Documentation with frontmatter -Additional information can be placed in the README file below the content listed above, using any number of headers. +### README Frontmatter -Additional image/video assets can be placed in one of two places: +Module README frontmatter must include: -1. In the same user namespace directory where that user's main content lives -2. If the image is an icon, it can be placed in the top-level `.icons` directory (this is done because a lot of modules will be based off the same products) +```yaml +--- +display_name: "Module Name" # Required - Name shown on Registry website +description: "What it does" # Required - Short description +icon: "../../../../.icons/tool.svg" # Required - Path to icon file +verified: false # Optional - Set by maintainers only +tags: ["tag1", "tag2"] # Required - Array of descriptive tags +--- +``` -## Releases +### README Requirements -The release process involves the following steps: +All README files must follow these rules: -### 1. Create and merge a new PR +- Must have frontmatter section with proper YAML +- Exactly one h1 header directly below frontmatter +- When increasing header levels, increment by one each time +- Use `tf` instead of `hcl` for code blocks -- Create a PR with your module changes -- Get your PR reviewed, approved, and merged into the `main` branch +### Best Practices -### 2. Prepare Release (Maintainer Task) +- Use descriptive variable names and descriptions +- Include helpful comments +- Test all functionality +- Follow existing code patterns in the module -After merging to `main`, a maintainer will: +--- -- Check out the merge commit: +## Versioning Guidelines - ```shell - git checkout MERGE_COMMIT_ID - ``` +After your PR is merged, maintainers will handle the release. Understanding version numbers helps you describe the impact of your changes: -- Create annotated tags for each module that was changed: +- **Patch** (1.2.3 β†’ 1.2.4): Bug fixes +- **Minor** (1.2.3 β†’ 1.3.0): New features, adding inputs +- **Major** (1.2.3 β†’ 2.0.0): Breaking changes (removing inputs, changing types) - ```shell - git tag -a "release/$namespace/$module/v$version" -m "Release $namespace/$module v$version" - ``` +**Important**: Always specify the version change in your PR (e.g., `v1.2.3 β†’ v1.2.4`). This helps maintainers create the correct release tag. -- Push the tags to origin: +--- - ```shell - git push origin release/$namespace/$module/v$version - ``` +## Reporting Issues -For example, to release version 1.0.14 of the coder/aider module: +When reporting bugs, include: -```shell -git tag -a "release/coder/aider/v1.0.14" -m "Release coder/aider v1.0.14" -git push origin release/coder/aider/v1.0.14 -``` +- Module name and version +- Expected vs actual behavior +- Minimal reproduction case +- Error messages +- Environment details (OS, Terraform version) -### Version Numbers +--- -Version numbers should follow semantic versioning: +## Getting Help -- **Patch version** (1.2.3 β†’ 1.2.4): Bug fixes -- **Minor version** (1.2.3 β†’ 1.3.0): New features, adding inputs, deprecating inputs -- **Major version** (1.2.3 β†’ 2.0.0): Breaking changes (removing inputs, changing input types) +- **Examples**: Check `/registry/coder/modules/` for well-structured modules +- **Issues**: Open an issue for technical problems +- **Community**: Reach out to the Coder community for questions -### 3. Publishing to Coder Registry +## Common Pitfalls -After tags are pushed, the changes will be published to [registry.coder.com](https://registry.coder.com). +1. **Missing frontmatter** in README +2. **No tests** or broken tests +3. **Hardcoded values** instead of variables +4. **Breaking changes** without defaults +5. **Not running** `bun fmt` before submitting -> [!NOTE] -> Some data in registry.coder.com is fetched on demand from this repository's `main` branch. This data should update almost immediately after a release, while other changes will take some time to propagate. +Happy contributing! πŸš€ diff --git a/MAINTAINER.md b/MAINTAINER.md new file mode 100644 index 000000000..69d1a6576 --- /dev/null +++ b/MAINTAINER.md @@ -0,0 +1,103 @@ +# Maintainer Guide + +Quick reference for maintaining the Coder Registry repository. + +## Setup + +Install Go for README validation: + +```bash +# macOS +brew install go + +# Linux +sudo apt install golang-go +``` + +## Daily Tasks + +### Review PRs + +Check that PRs have: + +- [ ] All required files (`main.tf`, `main.test.ts`, `README.md`) +- [ ] Proper frontmatter in README +- [ ] Working tests (`bun test`) +- [ ] Formatted code (`bun run fmt`) +- [ ] Avatar image for new namespaces (`avatar.png` or `avatar.svg` in `.images/`) + +#### Version Guidelines + +When reviewing PRs, ensure the version change follows semantic versioning: + +- **Patch** (1.2.3 β†’ 1.2.4): Bug fixes +- **Minor** (1.2.3 β†’ 1.3.0): New features, adding inputs +- **Major** (1.2.3 β†’ 2.0.0): Breaking changes (removing inputs, changing types) + +PRs should clearly indicate the version change (e.g., `v1.2.3 β†’ v1.2.4`). + +### Validate READMEs + +```bash +go build ./cmd/readmevalidation && ./readmevalidation +``` + +## Releases + +### Create Release Tags + +After merging a PR: + +1. Get the new version from the PR (shown as `old β†’ new`) +2. Checkout the merge commit and create the tag: + +```bash +# Checkout the merge commit +git checkout MERGE_COMMIT_ID + +# Create and push the release tag using the version from the PR +git tag -a "release/$namespace/$module/v$version" -m "Release $namespace/$module v$version" +git push origin release/$namespace/$module/v$version +``` + +Example: If PR shows `v1.2.3 β†’ v1.2.4`, use `v1.2.4` in the tag. + +### Publishing + +Changes are automatically published to [registry.coder.com](https://registry.coder.com) after tags are pushed. + +## README Requirements + +### Module Frontmatter (Required) + +```yaml +display_name: "Module Name" +description: "What it does" +icon: "../../../../.icons/tool.svg" +maintainer_github: "username" +partner_github: "partner-name" # Optional - For official partner modules +verified: false # Optional - Set by maintainers only +tags: ["tag1", "tag2"] +``` + +### Namespace Frontmatter (Required) + +```yaml +display_name: "Your Name" +bio: "Brief description of who you are and what you do" +avatar_url: "./.images/avatar.png" +github: "username" +linkedin: "https://www.linkedin.com/in/username" # Optional +website: "https://yourwebsite.com" # Optional +support_email: "you@example.com" # Optional +status: "community" # or "partner", "official" +``` + +## Common Issues + +- **README validation fails**: Check YAML syntax, ensure h1 header after frontmatter +- **Tests fail**: Ensure Docker with `--network=host`, check Terraform syntax +- **Wrong file structure**: Use `./scripts/new_module.sh` for new modules +- **Missing namespace avatar**: Must be `avatar.png` or `avatar.svg` in `.images/` directory + +That's it. Keep it simple.