docs: reorganize the About section (#18236)

As part of an information architecture overhaul, this PR reorganizes the
About section and adds a Support section (but not content to it yet)

[preview](https://coder.com/docs/@docs-ia-about/about)

this PR is intentionally limited in scope so that we can ship meaningful
changes faster and followup PRs should include:

- [ ] edit + overhaul the About page
- [ ] decide on the `start` directory
- [ ] ~screenshots page updates~ (this should happen July or later)

redirects PR: https://github.com/coder/coder.com/pull/944

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
This commit is contained in:
Edward Angert
2025-06-12 13:56:45 -04:00
committed by GitHub
co-authored by EdwardAngert
parent 5944b1c595
commit f1cca03ed3
19 changed files with 83 additions and 65 deletions
@@ -0,0 +1,77 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and
expression, level of experience, education, socio-economic status, nationality,
personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <opensource@coder.com>. All complaints
will be reviewed and investigated and will result in a response that is deemed
necessary and appropriate to the circumstances. The project team is obligated to
maintain confidentiality with regard to the reporter of an incident. Further
details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at
<https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
<https://www.contributor-covenant.org/faq>
+268
View File
@@ -0,0 +1,268 @@
# Contributing
## Requirements
<div class="tabs">
To get started with Coder, the easiest way to set up the required environment is to use the provided [Nix environment](https://github.com/coder/coder/tree/main/nix).
Learn more [how Nix works](https://nixos.org/guides/how-nix-works).
### Nix
1. [Install Nix](https://nix.dev/install-nix#install-nix)
1. After you've installed Nix, instantiate the development with the `nix-shell`
command:
```shell
cd ~/code/coder
# https://nix.dev/tutorials/declarative-and-reproducible-developer-environments
nix-shell
...
copying path '/nix/store/3ms6cs5210n8vfb5a7jkdvzrzdagqzbp-iana-etc-20210225' from 'https:// cache.nixos.org'...
copying path '/nix/store/dxg5aijpyy36clz05wjsyk90gqcdzbam-iana-etc-20220520' from 'https:// cache.nixos.org'...
copying path '/nix/store/v2gvj8whv241nj4lzha3flq8pnllcmvv-ignore-5.2.0.tgz' from 'https://cache. nixos.org'...
...
```
1. Optional: If you have [direnv](https://direnv.net/) installed with
[hooks configured](https://direnv.net/docs/hook.html), you can add `use nix`
to `.envrc` to automatically instantiate the development environment:
```shell
cd ~/code/coder
echo "use nix" >.envrc
direnv allow
```
Now, whenever you enter the project folder,
[`direnv`](https://direnv.net/docs/hook.html) will prepare the environment
for you:
```shell
cd ~/code/coder
direnv: loading ~/code/coder/.envrc
direnv: using nix
direnv: export +AR +AS +CC +CONFIG_SHELL +CXX +HOST_PATH +IN_NIX_SHELL +LD +NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_BUILD_CORES +NIX_BUILD_TOP +NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_CFLAGS_COMPILE +NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE +NIX_INDENT_MAKE +NIX_LDFLAGS +NIX_STORE +NM +NODE_PATH +OBJCOPY +OBJDUMP +RANLIB +READELF +SIZE +SOURCE_DATE_EPOCH +STRINGS +STRIP +TEMP +TEMPDIR +TMP +TMPDIR +XDG_DATA_DIRS +buildInputs +buildPhase +builder +cmakeFlags +configureFlags +depsBuildBuild +depsBuildBuildPropagated +depsBuildTarget +depsBuildTargetPropagated +depsHostHost +depsHostHostPropagated +depsTargetTarget +depsTargetTargetPropagated +doCheck +doInstallCheck +mesonFlags +name +nativeBuildInputs +out +outputs +patches +phases +propagatedBuildInputs +propagatedNativeBuildInputs +shell +shellHook +stdenv +strictDeps +system ~PATH
🎉
```
- If you encounter a `creating directory` error on macOS, check the
[troubleshooting](#troubleshooting) section below.
### Without Nix
If you're not using the Nix environment, you can launch a local [DevContainer](https://github.com/coder/coder/tree/main/.devcontainer) to get a fully configured development environment.
DevContainers are supported in tools like **VS Code** and **GitHub Codespaces**, and come preloaded with all required dependencies: Docker, Go, Node.js with `pnpm`, and `make`.
</div>
## Development workflow
Use the following `make` commands and scripts in development:
- `./scripts/develop.sh` runs the frontend and backend development server
- `make build` compiles binaries and release packages
- `make install` installs binaries to `$GOPATH/bin`
- `make test`
### Running Coder on development mode
1. Run the development script to spin up the local environment:
```sh
./scripts/develop.sh
```
This will start two processes:
- http://localhost:3000 — the backend API server. Primarily used for backend development and also serves the *static* frontend build.
- http://localhost:8080 — the Node.js frontend development server. Supports *hot reloading* and is useful if you're working on the frontend as well.
Additionally, it starts a local PostgreSQL instance, creates both an admin and a member user account, and installs a default Docker-based template.
1. Verify Your Session
Confirm that you're logged in by running:
```sh
./scripts/coder-dev.sh list
```
This should return an empty list of workspaces. If you encounter an error, review the output from the [develop.sh](https://github.com/coder/coder/blob/main/scripts/develop.sh) script for issues.
> `coder-dev.sh` is a helper script that behaves like the regular coder CLI, but uses the binary built from your local source and shares the same configuration directory set up by `develop.sh`. This ensures your local changes are reflected when testing.
>
> The default user is `admin@coder.com` and the default password is `SomeSecurePassword!`
1. Create Your First Workspace
A template named `docker` is created automatically. To spin up a workspace quickly, use:
```sh
./scripts/coder-dev.sh create my-workspace -t docker
```
### Deploying a PR
You need to be a member or collaborator of the [coder](https://github.com/coder) GitHub organization to be able to deploy a PR.
You can test your changes by creating a PR deployment. There are two ways to do
this:
- Run `./scripts/deploy-pr.sh`
- Manually trigger the
[`pr-deploy.yaml`](https://github.com/coder/coder/actions/workflows/pr-deploy.yaml)
GitHub Action workflow:
<Image src="./images/deploy-pr-manually.png" alt="Deploy PR manually" height="348px" align="center" />
#### Available options
- `-d` or `--deploy`, force deploys the PR by deleting the existing deployment.
- `-b` or `--build`, force builds the Docker image. (generally not needed as we
are intelligently checking if the image needs to be built)
- `-e EXPERIMENT1,EXPERIMENT2` or `--experiments EXPERIMENT1,EXPERIMENT2`, will
enable the specified experiments. (defaults to `*`)
- `-n` or `--dry-run` will display the context without deployment. e.g., branch
name and PR number, etc.
- `-y` or `--yes`, will skip the CLI confirmation prompt.
> [!NOTE]
> PR deployment will be re-deployed automatically when the PR is updated.
> It will use the last values automatically for redeployment.
Once the deployment is finished, a unique link and credentials will be posted in
the [#pr-deployments](https://codercom.slack.com/archives/C05DNE982E8) Slack
channel.
## Styling
- [Documentation style guide](./documentation.md)
- [Frontend styling guide](./frontend.md#styling)
## Reviews
The following information has been borrowed from [Go's review philosophy](https://go.dev/doc/contribute#reviews).
Coder values thorough reviews. For each review comment that you receive, please
"close" it by implementing the suggestion or providing an explanation on why the
suggestion isn't the best option. Be sure to do this for each comment; you can
click **Done** to indicate that you've implemented the suggestion, or you can
add a comment explaining why you aren't implementing the suggestion (or what you
chose to implement instead).
It is perfectly normal for changes to go through several rounds of reviews, with
one or more reviewers making new comments every time, then waiting for an
updated change before reviewing again. All contributors, including those from
maintainers, are subject to the same review cycle; this process is not meant to
be applied selectively or to discourage anyone from contributing.
## Releases
Coder releases are initiated via
[`./scripts/release.sh`](https://github.com/coder/coder/blob/main/scripts/release.sh)
and automated via GitHub Actions. Specifically, the
[`release.yaml`](https://github.com/coder/coder/blob/main/.github/workflows/release.yaml)
workflow. They are created based on the current
[`main`](https://github.com/coder/coder/tree/main) branch.
The release notes for a release are automatically generated from commit titles
and metadata from PRs that are merged into `main`.
### Creating a release
The creation of a release is initiated via
[`./scripts/release.sh`](https://github.com/coder/coder/blob/main/scripts/release.sh).
This script will show a preview of the release that will be created, and if you
choose to continue, create and push the tag which will trigger the creation of
the release via GitHub Actions.
See `./scripts/release.sh --help` for more information.
### Creating a release (via workflow dispatch)
Typically the workflow dispatch is only used to test (dry-run) a release,
meaning no actual release will take place. The workflow can be dispatched
manually from
[Actions: Release](https://github.com/coder/coder/actions/workflows/release.yaml).
Simply press "Run workflow" and choose dry-run.
If a release has failed after the tag has been created and pushed, it can be
retried by again, pressing "Run workflow", changing "Use workflow from" from
"Branch: main" to "Tag: vX.X.X" and not selecting dry-run.
### Commit messages
Commit messages should follow the
[Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/)
specification.
Allowed commit types (`feat`, `fix`, etc.) are listed in
[conventional-commit-types](https://github.com/commitizen/conventional-commit-types/blob/c3a9be4c73e47f2e8197de775f41d981701407fb/index.json).
Note that these types are also used to automatically sort and organize the
release notes.
A good commit message title uses the imperative, present tense and is ~50
characters long (no more than 72).
Examples:
- Good: `feat(api): add feature X`
- Bad: `feat(api): added feature X` (past tense)
A good rule of thumb for writing good commit messages is to recite:
[If applied, this commit will ...](https://reflectoring.io/meaningful-commit-messages/).
**Note:** We lint PR titles to ensure they follow the Conventional Commits
specification, however, it's still possible to merge PRs on GitHub with a badly
formatted title. Take care when merging single-commit PRs as GitHub may prefer
to use the original commit title instead of the PR title.
### Breaking changes
Breaking changes can be triggered in two ways:
- Add `!` to the commit message title, e.g.
`feat(api)!: remove deprecated endpoint /test`
- Add the
[`release/breaking`](https://github.com/coder/coder/issues?q=sort%3Aupdated-desc+label%3Arelease%2Fbreaking)
label to a PR that has, or will be, merged into `main`.
### Security
> [!CAUTION]
> If you find a vulnerability, **DO NOT FILE AN ISSUE**. Instead, send an email
> to <security@coder.com>.
The
[`security`](https://github.com/coder/coder/issues?q=sort%3Aupdated-desc+label%3Asecurity)
label can be added to PRs that have, or will be, merged into `main`. Doing so
will make sure the change stands out in the release notes.
### Experimental
The
[`release/experimental`](https://github.com/coder/coder/issues?q=sort%3Aupdated-desc+label%3Arelease%2Fexperimental)
label can be used to move the note to the bottom of the release notes under a
separate title.
## Troubleshooting
### Nix on macOS: `error: creating directory`
On macOS, a [direnv bug](https://github.com/direnv/direnv/issues/1345) can cause
`nix-shell` to fail to build or run `coder`. If you encounter
`error: creating directory` when you attempt to run, build, or test, add a
`mkdir` line to your `.envrc`:
```shell
use nix
mkdir -p "$TMPDIR"
```
+11
View File
@@ -0,0 +1,11 @@
# Security Policy
Coder welcomes feedback from security researchers and the general public to help improve our security.
If you believe you have discovered a vulnerability, privacy issue, exposed data, or other security issues
in any of our assets, we want to hear from you.
If you find a vulnerability, **DO NOT FILE AN ISSUE**.
Instead, send an email to
<security@coder.com>.
Refer to the [Security policy](https://coder.com/security/policy) for more information.
+219
View File
@@ -0,0 +1,219 @@
# Backend
This guide is designed to support both Coder engineers and community contributors in understanding our backend systems and getting started with development.
Coder’s backend powers the core infrastructure behind workspace provisioning, access control, and the overall developer experience. As the backbone of our platform, it plays a critical role in enabling reliable and scalable remote development environments.
The purpose of this guide is to help you:
* Understand how the various backend components fit together.
* Navigate the codebase with confidence and adhere to established best practices.
* Contribute meaningful changes - whether you're fixing bugs, implementing features, or reviewing code.
Need help or have questions? Join the conversation on our [Discord server](https://discord.com/invite/coder) — we’re always happy to support contributors.
## Platform Architecture
To understand how the backend fits into the broader system, we recommend reviewing the following resources:
* [General Concepts](../admin/infrastructure/validated-architectures/index.md#general-concepts): Essential concepts and language used to describe how Coder is structured and operated.
* [Architecture](../admin/infrastructure/architecture.md): A high-level overview of the infrastructure layout, key services, and how components interact.
These sections provide the necessary context for navigating and contributing to the backend effectively.
## Tech Stack
Coder's backend is built using a collection of robust, modern Go libraries and internal packages. Familiarity with these technologies will help you navigate the codebase and contribute effectively.
### Core Libraries & Frameworks
* [go-chi/chi](https://github.com/go-chi/chi): lightweight HTTP router for building RESTful APIs in Go
* [golang-migrate/migrate](https://github.com/golang-migrate/migrate): manages database schema migrations across environments
* [coder/terraform-config-inspect](https://github.com/coder/terraform-config-inspect) *(forked)*: used for parsing and analyzing Terraform configurations, forked to include [PR #74](https://github.com/hashicorp/terraform-config-inspect/pull/74)
* [coder/pq](https://github.com/coder/pq) *(forked)*: PostgreSQL driver forked to support rotating authentication tokens via `driver.Connector`
* [coder/tailscale](https://github.com/coder/tailscale) *(forked)*: enables secure, peer-to-peer connectivity, forked to apply internal patches pending upstreaming
* [coder/wireguard-go](https://github.com/coder/wireguard-go) *(forked)*: WireGuard networking implementation, forked to fix a data race and adopt the latest gVisor changes
* [coder/ssh](https://github.com/coder/ssh) *(forked)*: customized SSH server based on `gliderlabs/ssh`, forked to include Tailscale-specific patches and avoid complex subpath dependencies
* [coder/bubbletea](https://github.com/coder/bubbletea) *(forked)*: terminal UI framework for CLI apps, forked to remove an `init()` function that interfered with web terminal output
### Coder libraries
* [coder/terraform-provider-coder](https://github.com/coder/terraform-provider-coder): official Terraform provider for managing Coder resources via infrastructure-as-code
* [coder/websocket](https://github.com/coder/websocket): minimal WebSocket library for real-time communication
* [coder/serpent](https://github.com/coder/serpent): CLI framework built on `cobra`, used for large, complex CLIs
* [coder/guts](https://github.com/coder/guts): generates TypeScript types from Go for shared type definitions
* [coder/wgtunnel](https://github.com/coder/wgtunnel): WireGuard tunnel server for secure backend networking
## Repository Structure
The Coder backend is organized into multiple packages and directories, each with a specific purpose. Here's a high-level overview of the most important ones:
* [agent](https://github.com/coder/coder/tree/main/agent): core logic of a workspace agent, supports DevContainers, remote SSH, startup/shutdown script execution. Protobuf definitions for DRPC communication with `coderd` are kept in [proto](https://github.com/coder/coder/tree/main/agent/proto).
* [cli](https://github.com/coder/coder/tree/main/cli): CLI interface for `coder` command built on [coder/serpent](https://github.com/coder/serpent). Input controls are defined in [cliui](https://github.com/coder/coder/tree/docs-backend-contrib-guide/cli/cliui), and [testdata](https://github.com/coder/coder/tree/docs-backend-contrib-guide/cli/testdata) contains golden files for common CLI calls
* [cmd](https://github.com/coder/coder/tree/main/cmd): entry points for CLI and services, including `coderd`
* [coderd](https://github.com/coder/coder/tree/main/coderd): the main API server implementation with [chi](https://github.com/go-chi/chi) endpoints
* [audit](https://github.com/coder/coder/tree/main/coderd/audit): audit log logic, defines target resources, actions and extra fields
* [autobuild](https://github.com/coder/coder/tree/main/coderd/autobuild): core logic of the workspace autobuild executor, periodically evaluates workspaces for next transition actions
* [httpmw](https://github.com/coder/coder/tree/main/coderd/httpmw): HTTP middlewares mainly used to extract parameters from HTTP requests (e.g. current user, template, workspace, OAuth2 account, etc.) and storing them in the request context
* [prebuilds](https://github.com/coder/coder/tree/main/coderd/prebuilds): common interfaces for prebuild workspaces, feature implementation is in [enterprise/prebuilds](https://github.com/coder/coder/tree/main/enterprise/coderd/prebuilds)
* [provisionerdserver](https://github.com/coder/coder/tree/main/coderd/provisionerdserver): DRPC server for [provisionerd](https://github.com/coder/coder/tree/main/provisionerd) instances, used to validate and extract Terraform data and resources, and store them in the database.
* [rbac](https://github.com/coder/coder/tree/main/coderd/rbac): RBAC engine for `coderd`, including authz layer, role definitions and custom roles. Built on top of [Open Policy Agent](https://github.com/open-policy-agent/opa) and Rego policies.
* [telemetry](https://github.com/coder/coder/tree/main/coderd/telemetry): records a snapshot with various workspace data for telemetry purposes. Once recorded the reporter sends it to the configured telemetry endpoint.
* [tracing](https://github.com/coder/coder/tree/main/coderd/tracing): extends telemetry with tracing data consistent with [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md)
* [workspaceapps](https://github.com/coder/coder/tree/main/coderd/workspaceapps): core logic of a secure proxy to expose workspace apps deployed in a workspace
* [wsbuilder](https://github.com/coder/coder/tree/main/coderd/wsbuilder): wrapper for business logic of creating a workspace build. It encapsulates all database operations required to insert a build record in a transaction.
* [database](https://github.com/coder/coder/tree/main/coderd/database): schema migrations, query logic, in-memory database, etc.
* [db2sdk](https://github.com/coder/coder/tree/main/coderd/database/db2sdk): translation between database structures and [codersdk](https://github.com/coder/coder/tree/main/codersdk) objects used by coderd API.
* [dbauthz](https://github.com/coder/coder/tree/main/coderd/database/dbauthz): AuthZ wrappers for database queries, ideally, every query should verify first if the accessor is eligible to see the query results.
* [dbfake](https://github.com/coder/coder/tree/main/coderd/database/dbfake): helper functions to quickly prepare the initial database state for testing purposes (e.g. create N healthy workspaces and templates), operates on higher level than [dbgen](https://github.com/coder/coder/tree/main/coderd/database/dbgen)
* [dbgen](https://github.com/coder/coder/tree/main/coderd/database/dbgen): helper functions to insert raw records to the database store, used for testing purposes
* [dbmem](https://github.com/coder/coder/tree/main/coderd/database/dbmem): in-memory implementation of the database store, ideally, every real query should have a complimentary Go implementation
* [dbmock](https://github.com/coder/coder/tree/main/coderd/database/dbmock): a store wrapper for database queries, useful to verify if the function has been called, used for testing purposes
* [dbpurge](https://github.com/coder/coder/tree/main/coderd/database/dbpurge): simple wrapper for periodic database cleanup operations
* [migrations](https://github.com/coder/coder/tree/main/coderd/database/migrations): an ordered list of up/down database migrations, use `./create_migration.sh my_migration_name` to modify the database schema
* [pubsub](https://github.com/coder/coder/tree/main/coderd/database/pubsub): PubSub implementation using PostgreSQL and in-memory drop-in replacement
* [queries](https://github.com/coder/coder/tree/main/coderd/database/queries): contains SQL files with queries, `sqlc` compiles them to [Go functions](https://github.com/coder/coder/blob/docs-backend-contrib-guide/coderd/database/queries.sql.go)
* [sqlc.yaml](https://github.com/coder/coder/tree/main/coderd/database/sqlc.yaml): defines mappings between SQL types and custom Go structures
* [codersdk](https://github.com/coder/coder/tree/main/codersdk): user-facing API entities used by CLI and site to communicate with `coderd` endpoints
* [dogfood](https://github.com/coder/coder/tree/main/dogfood): Terraform definition of the dogfood cluster deployment
* [enterprise](https://github.com/coder/coder/tree/main/enterprise): enterprise-only features, notice similar file structure to repository root (`audit`, `cli`, `cmd`, `coderd`, etc.)
* [coderd](https://github.com/coder/coder/tree/main/enterprise/coderd)
* [prebuilds](https://github.com/coder/coder/tree/main/enterprise/coderd/prebuilds): core logic of prebuilt workspaces - reconciliation loop
* [provisioner](https://github.com/coder/coder/tree/main/provisioner): supported implementation of provisioners, Terraform and "echo" (for testing purposes)
* [provisionerd](https://github.com/coder/coder/tree/main/provisionerd): core logic of provisioner runner to interact provisionerd server, depending on a job acquired it calls template import, dry run or a workspace build
* [pty](https://github.com/coder/coder/tree/main/pty): terminal emulation for agent shell
* [support](https://github.com/coder/coder/tree/main/support): compile a support bundle with diagnostics
* [tailnet](https://github.com/coder/coder/tree/main/tailnet): core logic of Tailnet controller to maintain DERP maps, coordinate connections with agents and peers
* [vpn](https://github.com/coder/coder/tree/main/vpn): Coder Desktop (VPN) and tunneling components
## Testing
The Coder backend includes a rich suite of unit and end-to-end tests. A variety of helper utilities are used throughout the codebase to make testing easier, more consistent, and closer to real behavior.
### [clitest](https://github.com/coder/coder/tree/main/cli/clitest)
* Spawns an in-memory `serpent.Command` instance for unit testing
* Configures an authorized `codersdk` client
* Once a `serpent.Invocation` is created, tests can execute commands as if invoked by a real user
### [ptytest](https://github.com/coder/coder/tree/main/pty/ptytest)
* `ptytest` attaches to a `serpent.Invocation` and simulates TTY input/output
* `pty` provides matchers and "write" operations for interacting with pseudo-terminals
### [coderdtest](https://github.com/coder/coder/tree/main/coderd/coderdtest)
* Provides shortcuts to spin up an in-memory `coderd` instance
* Can start an embedded provisioner daemon
* Supports multi-user testing via `CreateFirstUser` and `CreateAnotherUser`
* Includes "busy wait" helpers like `AwaitTemplateVersionJobCompleted`
* [oidctest](https://github.com/coder/coder/tree/main/coderd/coderdtest/oidctest) can start a fake OIDC provider
### [testutil](https://github.com/coder/coder/tree/main/testutil)
* General-purpose testing utilities, including:
* [chan.go](https://github.com/coder/coder/blob/main/testutil/chan.go): helpers for sending/receiving objects from channels (`TrySend`, `RequireReceive`, etc.)
* [duration.go](https://github.com/coder/coder/blob/main/testutil/duration.go): set timeouts for test execution
* [eventually.go](https://github.com/coder/coder/blob/main/testutil/eventually.go): repeatedly poll for a condition using a ticker
* [port.go](https://github.com/coder/coder/blob/main/testutil/port.go): select a free random port
* [prometheus.go](https://github.com/coder/coder/blob/main/testutil/prometheus.go): validate Prometheus metrics with expected values
* [pty.go](https://github.com/coder/coder/blob/main/testutil/pty.go): read output from a terminal until a condition is met
### [dbtestutil](https://github.com/coder/coder/tree/main/coderd/database/dbtestutil)
* Allows choosing between real and in-memory database backends for tests
* `WillUsePostgres` is useful for skipping tests in CI environments that don't run Postgres
### [quartz](https://github.com/coder/quartz/tree/main)
* Provides a mockable clock or ticker interface
* Allows manual time advancement
* Useful for testing time-sensitive or timeout-related logic
## Quiz
Try to find answers to these questions before jumping into implementation work — having a solid understanding of how Coder works will save you time and help you contribute effectively.
1. When you create a template, what does that do exactly?
2. When you create a workspace, what exactly happens?
3. How does the agent get the required information to run?
4. How are provisioner jobs run?
## Recipes
### Adding database migrations and fixtures
#### Database migrations
Database migrations are managed with
[`migrate`](https://github.com/golang-migrate/migrate).
To add new migrations, use the following command:
```shell
./coderd/database/migrations/create_migration.sh my name
/home/coder/src/coder/coderd/database/migrations/000070_my_name.up.sql
/home/coder/src/coder/coderd/database/migrations/000070_my_name.down.sql
```
Then write queries into the generated `.up.sql` and `.down.sql` files and commit
them into the repository. The down script should make a best-effort to retain as
much data as possible.
Run `make gen` to generate models.
#### Database fixtures (for testing migrations)
There are two types of fixtures that are used to test that migrations don't
break existing Coder deployments:
* Partial fixtures
[`migrations/testdata/fixtures`](../../coderd/database/migrations/testdata/fixtures)
* Full database dumps
[`migrations/testdata/full_dumps`](../../coderd/database/migrations/testdata/full_dumps)
Both types behave like database migrations (they also
[`migrate`](https://github.com/golang-migrate/migrate)). Their behavior mirrors
Coder migrations such that when migration number `000022` is applied, fixture
`000022` is applied afterwards.
Partial fixtures are used to conveniently add data to newly created tables so
that we can ensure that this data is migrated without issue.
Full database dumps are for testing the migration of fully-fledged Coder
deployments. These are usually done for a specific version of Coder and are
often fixed in time. A full database dump may be necessary when testing the
migration of multiple features or complex configurations.
To add a new partial fixture, run the following command:
```shell
./coderd/database/migrations/create_fixture.sh my fixture
/home/coder/src/coder/coderd/database/migrations/testdata/fixtures/000070_my_fixture.up.sql
```
Then add some queries to insert data and commit the file to the repo. See
[`000024_example.up.sql`](../../coderd/database/migrations/testdata/fixtures/000024_example.up.sql)
for an example.
To create a full dump, run a fully fledged Coder deployment and use it to
generate data in the database. Then shut down the deployment and take a snapshot
of the database.
```shell
mkdir -p coderd/database/migrations/testdata/full_dumps/v0.12.2 && cd $_
pg_dump "postgres://coder@localhost:..." -a --inserts >000069_dump_v0.12.2.up.sql
```
Make sure sensitive data in the dump is desensitized, for instance names,
emails, OAuth tokens and other secrets. Then commit the dump to the project.
To find out what the latest migration for a version of Coder is, use the
following command:
```shell
git ls-files v0.12.2 -- coderd/database/migrations/*.up.sql
```
This helps in naming the dump (e.g. `000069` above).
+149
View File
@@ -0,0 +1,149 @@
# Documentation
This style guide is primarily for use with authoring documentation.
## General guidelines
- Use sentence case, even in titles (do not punctuate the title, though)
- Use the second person
- Use the active voice
- Use plural nouns and pronouns (_they_, _their_, or _them_), especially when
the specific number is uncertain (i.e., "Set up your environments" even though
you don't know if the user will have one or many environments)
- When writing documentation titles, use the noun form, not the gerund form
(e.g., "Environment Management" instead of "Managing Environments")
- Context matters when you decide whether to capitalize something or not. For
example,
["A Job creates one or more Pods..."](https://kubernetes.io/docs/concepts/workloads/controllers/job/)
is correct when writing about Kubernetes. However, in other contexts, neither
_job_ nor _pods_ would be capitalized. Please follow the conventions set forth
by the relevant companies and open source communities.
## Third-party references
If you have questions that aren't explicitly covered by this guide, consult the
following third-party references:
| **Type of guidance** | **Third-party reference** |
|----------------------|----------------------------------------------------------------------------------------|
| Spelling | [Merriam-Webster.com](https://www.merriam-webster.com/) |
| Style - nontechnical | [The Chicago Manual of Style](https://www.chicagomanualofstyle.org/home.html) |
| Style - technical | [Microsoft Writing Style Guide](https://docs.microsoft.com/en-us/style-guide/welcome/) |
## Tools
The following are tools that you can use to edit your writing. However, take the
suggestions provided with a grain of salt.
- [alex.js](https://alexjs.com/)
- [Grammarly](https://app.grammarly.com/)
- [Hemingway Editor](https://hemingwayapp.com/)
## How to format text
Below summarizes the text-formatting conventions you should follow.
### Bold
Use **bold** formatting when referring to UI elements.
### Italics
Use _italics_ for:
- Parameter names
- Mathematical and version variables
### Code font
Use _code font_ for:
- User text input
- Command-line utility names
- DNS record types
- Environment variable names (e.g., `PATH`)
- Filenames, filename extensions, and paths
- Folders and directories
- HTTP verbs, status codes, and content-type values
- Placeholder variables
Use _code blocks_ for code samples and other blocks of code. Be sure to indicate
the language your using to apply the proper syntax highlighting.
```text
This is a codeblock.
```
For code that you want users to enter via a command-line interface, use
`console`, not `bash`.
### Punctuation
Do not use the ampersand (&) as a shorthand for _and_ unless you're referring to
a UI element or the name of something that uses _&_.
You can use the symbol `~` in place of the word _approximately_.
### UI elements
When referring to UI elements, including the names for buttons, menus, dialogs,
and anything that has a name visible to the user, use bold font.
**Example:** On the **Environment Overview** page, click **Configure SSH**.
Don't use code font for UI elements unless it is rendered based on previously
entered text. For example, if you tell the user to provide the environment name
as `myEnvironment`, then use both bold and cold font when referring to the name.
**Example**: Click **`myEnvironment`**.
When writing out instructions that involve UI elements, both of the following
options are acceptable:
- Go to **Manage** > **Users**.
- In the **Manage** menu, click **Users**.
## Product-specific references
Below summarizes the guidelines regarding how Coder terms should be used.
### Capitalized terms
The only Coder-specific terms that should be capitalized are the names of
products (e.g., Coder).
The exception is **code-server**, which is always lowercase. If it appears at
the beginning of the sentence, rewrite the sentence to avoid this usage.
### Uncapitalized terms
In general, we do not capitalize the names of features (unless the situation
calls for it, such as the word appearing at the beginning of a sentence):
- account dormancy
- audit logs
- autostart
- command-line interface
- dev URLs
- environment
- image
- metrics
- organizations
- progressive web app
- registries
- single sign-on
- telemetry
- workspace
- workspace providers
- workspaces as code
We also do not capitalize the names of user roles:
- auditor
- member
- site admin
- site manager
## Standardized spellings
- WiFi
+378
View File
@@ -0,0 +1,378 @@
# Frontend
Welcome to the guide for contributing to the Coder frontend. Whether you’re part
of the community or a Coder team member, this documentation will help you get
started.
If you have any questions, feel free to reach out on our
[Discord server](https://discord.com/invite/coder), and we’ll be happy to assist
you.
## Running the UI
You can run the UI and access the Coder dashboard in two ways:
1. Build the UI pointing to an external Coder server:
`CODER_HOST=https://mycoder.com pnpm dev` inside of the `site` folder. This
is helpful when you are building something in the UI and already have the
data on your deployed server.
2. Build the entire Coder server + UI locally: `./scripts/develop.sh` in the
root folder. This is useful for contributing to features that are not
deployed yet or that involve both the frontend and backend.
In both cases, you can access the dashboard on `http://localhost:8080`. If using
`./scripts/develop.sh` you can log in with the default credentials.
> [!NOTE]
> **Default Credentials:** `admin@coder.com` and `SomeSecurePassword!`.
## Tech Stack Overview
All our dependencies are described in `site/package.json`, but the following are
the most important.
- [React](https://reactjs.org/) for the UI framework
- [Typescript](https://www.typescriptlang.org/) to keep our sanity
- [Vite](https://vitejs.dev/) to build the project
- [Material V5](https://mui.com/material-ui/getting-started/) for UI components
- [react-router](https://reactrouter.com/en/main) for routing
- [TanStack Query v4](https://tanstack.com/query/v4/docs/react/overview) for
fetching data
- [axios](https://github.com/axios/axios) as fetching lib
- [Playwright](https://playwright.dev/) for end-to-end (E2E) testing
- [Jest](https://jestjs.io/) for integration testing
- [Storybook](https://storybook.js.org/) and
[Chromatic](https://www.chromatic.com/) for visual testing
- [PNPM](https://pnpm.io/) as the package manager
## Structure
All UI-related code is in the `site` folder. Key directories include:
- **e2e** - End-to-end (E2E) tests
- **src** - Source code
- **mocks** - [Manual mocks](https://jestjs.io/docs/manual-mocks) used by Jest
- **@types** - Custom types for dependencies that don't have defined types
(largely code that has no server-side equivalent)
- **api** - API function calls and types
- **queries** - react-query queries and mutations
- **components** - Reusable UI components without Coder specific business
logic
- **hooks** - Custom React hooks
- **modules** - Coder-specific UI components
- **pages** - Page-level components
- **testHelpers** - Helper functions for integration testing
- **theme** - theme configuration and color definitions
- **util** - Helper functions that can be used across the application
- **static** - Static assets like images, fonts, icons, etc
## Routing
We use [react-router](https://reactrouter.com/en/main) as our routing engine.
- Authenticated routes - Place routes requiring authentication inside the
`<RequireAuth>` route. The `RequireAuth` component handles all the
authentication logic for the routes.
- Dashboard routes - routes that live in the dashboard should be placed under
the `<DashboardLayout>` route. The `DashboardLayout` adds a navbar and passes
down common dashboard data.
## Pages
Page components are the top-level components of the app and reside in the
`src/pages` folder. Each page should have its own folder to group relevant
views, tests, and utility functions. The page component fetches necessary data
and passes to the view. We explain this decision a bit better in the next
section which talks about where to fetch data.
If code within a page becomes reusable across other parts of the app,
consider moving it to `src/utils`, `hooks`, `components`, or `modules`.
### Handling States
A page typically has three states: **loading**, **ready**/**success**, and
**error**. Ensure you manage these states when developing pages. Use visual
tests for these states with `*.stories.ts` files.
## Data Fetching
We use [TanStack Query v4](https://tanstack.com/query/v4/docs/react/quick-start)
to fetch data from the API. Queries and mutation should be placed in the
api/queries folder.
### Where to fetch data
In the past, our approach involved creating separate components for page and
view, where the page component served as a container responsible for fetching
data and passing it down to the view.
For instance, when developing a page to display users, we would have a
`UsersPage` component with a corresponding `UsersPageView`. The `UsersPage`
would handle API calls, while the `UsersPageView` managed the presentational
logic.
Over time, however, we encountered challenges with this approach, particularly
in terms of excessive props drilling. To address this, we opted to fetch data in
proximity to its usage. Taking the example of displaying users, in the past, if
we were creating a header component for that page, we would have needed to fetch
the data in the page component and pass it down through the hierarchy
(`UsersPage -> UsersPageView -> UsersHeader`). Now, with libraries such as
`react-query`, data fetching can be performed directly in the `UsersHeader`
component, allowing UI elements to declare and consume their data-fetching
dependencies directly, while preventing duplicate server requests
([more info](https://github.com/TanStack/query/discussions/608#discussioncomment-29735)).
To simplify visual testing of scenarios where components are responsible for
fetching data, you can easily set the queries' value using `parameters.queries`
within the component's story.
```tsx
export const WithQuota: Story = {
parameters: {
queries: [
{
key: getWorkspaceQuotaQueryKey(MockUserOwner.username),
data: {
credits_consumed: 2,
budget: 40,
},
},
],
},
};
```
### API
Our project uses [axios](https://github.com/axios/axios) as the HTTP client for
making API requests. The API functions are centralized in `site/src/api/api.ts`.
Auto-generated TypeScript types derived from our Go server are located in
`site/src/api/typesGenerated.ts`.
Typically, each API endpoint corresponds to its own `Request` and `Response`
types. However, some endpoints require additional parameters for successful
execution. Here's an illustrative example:"
```ts
export const getAgentListeningPorts = async (
agentID: string,
): Promise<TypesGen.ListeningPortsResponse> => {
const response = await axiosInstance.get(
`/api/v2/workspaceagents/${agentID}/listening-ports`,
);
return response.data;
};
```
Sometimes, a frontend operation can have multiple API calls which can be wrapped
as a single function.
```ts
export const updateWorkspaceVersion = async (
workspace: TypesGen.Workspace,
): Promise<TypesGen.WorkspaceBuild> => {
const template = await getTemplate(workspace.template_id);
return startWorkspace(workspace.id, template.active_version_id);
};
```
## Components and Modules
Components should be atomic, reusable and free of business logic. Modules are
similar to components except that they can be more complex and can contain
business logic specific to the product.
### MUI
The codebase is currently using MUI v5. Please see the
[official documentation](https://mui.com/material-ui/getting-started/). In
general, favor building a custom component via MUI instead of plain React/HTML,
as MUI's suite of components is thoroughly battle-tested and accessible right
out of the box.
### Structure
Each component and module gets its own folder. Module folders may group multiple
files in a hierarchical structure. Storybook stories and component tests using
Storybook interactions are required. By keeping these tidy, the codebase will
remain easy to navigate, healthy and maintainable for all contributors.
### Accessibility
We strive to keep our UI accessible.
In general, colors should come from the app theme, but if there is a need to add
a custom color, please ensure that the foreground and background have a minimum
contrast ratio of 4.5:1 to meet WCAG level AA compliance. WebAIM has
[a great tool for checking your colors directly](https://webaim.org/resources/contrastchecker/),
but tools like
[Dequeue's axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd)
can also do automated checks in certain situations.
When using any kind of input element, always make sure that there is a label
associated with that element (the label can be made invisible for aesthetic
reasons, but it should always be in the HTML markup). Labels are important for
screen-readers; a placeholder text value is not enough for all users.
When possible, make sure that all image/graphic elements have accompanying text
that describes the image. `<img />` elements should have an `alt` text value. In
other situations, it might make sense to place invisible, descriptive text
inside the component itself using MUI's `visuallyHidden` utility function.
```tsx
import { visuallyHidden } from "@mui/utils";
<Button>
<GearIcon />
<Box component="span" sx={visuallyHidden}>
Settings
</Box>
</Button>;
```
### Should I create a new component or module?
Components could technically be used in any codebase and still feel at home. A
module would only make sense in the Coder codebase.
- Component
- Simple
- Atomic, used in multiple places
- Generic, would be useful as a component outside of the Coder product
- Good Examples: `Badge`, `Form`, `Timeline`
- Module
- Simple or Complex
- Used in multiple places
- Good Examples: `Provisioner`, `DashboardLayout`, `DeploymentBanner`
Our codebase has some legacy components that are being updated to follow these
new conventions, but all new components should follow these guidelines.
## Styling
We use [Emotion](https://emotion.sh/) to handle CSS styles.
## Forms
We use [Formik](https://formik.org/docs) for forms along with
[Yup](https://github.com/jquense/yup) for schema definition and validation.
## Testing
We use three types of testing in our app: **End-to-end (E2E)**, **Integration**
and **Visual Testing**.
### End-to-End (E2E)
These are useful for testing complete flows like "Create a user", "Import
template", etc. We use [Playwright](https://playwright.dev/). If you only need
to test if the page is being rendered correctly, you should consider using the
**Visual Testing** approach.
For scenarios where you need to be authenticated, you can use
`test.use({ storageState: getStatePath("authState") })`.
For ease of debugging, it's possible to run a Playwright test in headful mode
running a Playwright server on your local machine, and executing the test inside
your workspace.
You can either run `scripts/remote_playwright.sh` from `coder/coder` on your
local machine, or execute the following command if you don't have the repo
available:
```bash
bash <(curl -sSL https://raw.githubusercontent.com/coder/coder/main/scripts/remote_playwright.sh) [workspace]
```
The `scripts/remote_playwright.sh` script will start a Playwright server on your
local machine and forward the necessary ports to your workspace. At the end of
the script, you will land _inside_ your workspace with environment variables set
so you can simply execute the test (`pnpm run playwright:test`).
### Integration
Test user interactions like "Click in a button shows a dialog", "Submit the form
sends the correct data", etc. For this, we use [Jest](https://jestjs.io/) and
[react-testing-library](https://testing-library.com/docs/react-testing-library/intro/).
If the test involves routing checks like redirects or maybe checking the info on
another page, you should probably consider using the **E2E** approach.
### Visual testing
We use visual tests to test components without user interaction like testing if
a page/component is rendered correctly depending on some parameters, if a button
is showing a spinner, if `loading` props are passed correctly, etc. This should
always be your first option since it is way easier to maintain. For this, we use
[Storybook](https://storybook.js.org/) and
[Chromatic](https://www.chromatic.com/).
To learn more about testing components that fetch API data, refer to the
[**Where to fetch data**](#where-to-fetch-data) section.
### What should I test?
Choosing what to test is not always easy since there are a lot of flows and a
lot of things can happen but these are a few indicators that can help you with
that:
- Things that can block the user
- Reported bugs
- Regression issues
### Tests getting too slow
You may have observed that certain tests in our suite can be notably
time-consuming. Sometimes it is because the test itself is complex and sometimes
it is because of how the test is querying elements.
#### Using `ByRole` queries
One thing we figured out that was slowing down our tests was the use of `ByRole`
queries because of how it calculates the role attribute for every element on the
`screen`. You can read more about it on the links below:
- <https://stackoverflow.com/questions/69711888/react-testing-library-getbyrole-is-performing-extremely-slowly>
- <https://github.com/testing-library/dom-testing-library/issues/552#issuecomment-625172052>
Even with `ByRole` having performance issues we still want to use it but for
that, we have to scope the "querying" area by using the `within` command. So
instead of using `screen.getByRole("button")` directly we could do
`within(form).getByRole("button")`.
❌ Not ideal. If the screen has a hundred or thousand elements it can be VERY
slow.
```tsx
user.click(screen.getByRole("button"));
```
✅ Better. We can limit the number of elements we are querying.
```tsx
const form = screen.getByTestId("form");
user.click(within(form).getByRole("button"));
```
❌ Does not work
```ts
import { getUpdateCheck } from "api/api"
createMachine({ ... }, {
services: {
getUpdateCheck,
},
})
```
✅ It works
```ts
import { getUpdateCheck } from "api/api"
createMachine({ ... }, {
services: {
getUpdateCheck: () => getUpdateCheck(),
},
})
```
+59
View File
@@ -0,0 +1,59 @@
# Screenshots
## Log in
![Install Coder in your cloud or air-gapped on-premises. Developers simply log in via their browser to access their Workspaces.](../images/screenshots/login.png)
Install Coder in your cloud or air-gapped on-premises. Developers simply log in
via their browser to access their Workspaces.
## Templates
![Developers provision their own ephemeral Workspaces in minutes using pre-defined Templates that include approved tooling and infrastructure.](../images/screenshots/templates_listing.png)
Developers provision their own ephemeral Workspaces in minutes using pre-defined
Templates that include approved tooling and infrastructure.
![Template administrators can either create a new Template from scratch or choose a Starter Template](../images/screenshots/starter_templates.png)
Template administrators can either create a new Template from scratch or choose
a Starter Template.
![Templates define the underlying infrastructure that Coder Workspaces run on.](../images/screenshots/terraform.png)
Template administrators build Templates using Terraform. Templates define the
underlying infrastructure that Coder Workspaces run on.
## Workspaces
![Developers create and delete their own workspaces. Coder administrators can easily enforce Workspace scheduling and autostop policies to ensure idle Workspaces don’t burn unnecessary cloud budget.](../images/screenshots/workspaces_listing.png)
Developers create and delete their own workspaces. Coder administrators can
easily enforce Workspace scheduling and autostop policies to ensure idle
Workspaces don’t burn unnecessary cloud budget.
![Developers launch their favorite web-based or desktop IDE, browse files, or access their Workspace’s Terminal.](../images/screenshots/workspace_launch.png)
Developers launch their favorite web-based or desktop IDE, browse files, or
access their Workspace’s Terminal.
## Administration
![Coder administrators can access Template usage insights to understand which Templates are most popular and how well they perform for developers.](../images/screenshots/templates_insights.png)
Coder administrators can access Template usage insights to understand which
Templates are most popular and how well they perform for developers.
![Coder administrators can control *every* aspect of their Coder deployment.](../images/screenshots/settings.png)
Coder administrators can control *every* aspect of their Coder deployment.
![Coder administrators and auditor roles can review how users are interacting with their Coder Workspaces and Templates.](../images/screenshots/audit.png)
Coder administrators and auditor roles can review how users are interacting with
their Coder Workspaces and Templates.
![Coder administrators can monitor the health of their Coder deployment, including database latency, active provisioners, and more.](../images/screenshots/healthcheck.png)
Coder administrators can monitor the health of their Coder deployment, including
database latency, active provisioners, and more.
+3
View File
@@ -0,0 +1,3 @@
# Why use Coder
TODO: Make this page!