Compare commits

..

816 Commits

Author SHA1 Message Date
Jakub Domeracki de62750d7f chore: revert CLI binary publishing for releases.coder.com (#19234) 2025-08-07 11:06:03 -05:00
Jakub Domeracki 9eaecf1425 chore: fix CLI binary publishing for releases.coder.com (#19229) 2025-08-07 17:17:03 +02:00
Spike Curtis 580081c76f fix: upgrade to 1.24.6 to fix race in lib/pq queries (#19214) (#19220)
THIS IS A SECURITY FIX - cherry picks #19214 

upgrade to go 1.24.6 to avoid https://github.com/golang/go/issues/74831
(CVE-2025-47907)

Also points to a new version of our lib/pq fork that worked around the
Go issue, which should restore better performance.

---------

Co-authored-by: Cian Johnston <cian@coder.com>
Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
2025-08-07 15:13:36 +04:00
Jakub Domeracki 54d0575fde chore: publish CLI binaries and detached signatures to releases.coder.com (#18900)
Cherry pick
(https://github.com/coder/coder/commit/e4d3453e2b55edfc5a9650083f4bffc765423b1c)

Starting with version `2.24.X `, Coder CLI binaries & corresponding
detached signatures will get published to the GCS bucket
releases.coder.com.
2025-07-16 14:15:26 +02:00
Dean Sheather 1c8ba51410 cherry: feat: sign coder binaries with the release key using GPG (#18774) (#18867)
(cherry picked from commit dc0919da33)

Co-authored-by: Jakub Domeracki <jakub@coder.com>
2025-07-15 18:23:02 +10:00
gcp-cherry-pick-bot[bot] 63155d2d0a chore: add rdp icon (cherry-pick #18736) (#18738)
Co-authored-by: Atif Ali <atif@coder.com>
2025-07-14 10:45:47 +05:00
gcp-cherry-pick-bot[bot] a7f0dba4c3 fix(cli): handle nil unwrap errors when formatting (cherry-pick #18099) (#18821)
Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
2025-07-10 10:43:57 +05:00
gcp-cherry-pick-bot[bot] 049feeca76 fix: handle paths with spaces in Match exec clause of SSH config (cherry-pick #18266) (#18778)
Co-authored-by: Spike Curtis <spike@coder.com>
fixes #18199
2025-07-08 10:14:31 -05:00
gcp-cherry-pick-bot[bot] 75e7a93598 fix: stop tearing down non-TTY processes on SSH session end (cherry-pick #18673) (#18677)
Cherry-picked fix: stop tearing down non-TTY processes on SSH session
end (#18673)

(possibly temporary) fix for #18519

Matches OpenSSH for non-tty sessions, where we don't actively terminate
the process.

Adds explicit tracking to the SSH server for these processes so that if
we are shutting down we terminate them: this ensures that we can shut
down quickly to allow shutdown scripts to run. It also ensures our tests
don't leak system resources.

Co-authored-by: Spike Curtis <spike@coder.com>
2025-06-30 23:09:47 +04:00
gcp-cherry-pick-bot[bot] 8e8dd58506 fix(site): remove trailing comment from cursor.svg (cherry-pick #18072) (#18378)
Cherry-picked fix(site): remove trailing comment from cursor.svg
(#18072)

The trailing comment was preventing the SVG from rendering on Coder
Desktop macOS, with the SVG loader we use. I've moved it to a place
where it's apparently OK? Couldn't tell you why.
https://validator.w3.org/ had no complaints.

I tested this by hardcoding the icon to that served by a build of coder
with this new svg.



![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/jI7h94jB23BidWsYTSCk/4c94ae5f-d0e2-496e-90eb-4968cf40d639.png)

The first icon is without the trailing comment, the second is with.

Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
2025-06-16 13:36:44 +10:00
gcp-cherry-pick-bot[bot] bc089f3410 chore: add windows icon (cherry-pick #18312) (#18322)
Co-authored-by: ケイラ <mckayla@hey.com>
2025-06-11 13:27:38 +05:00
Cian Johnston b906c16b3b chore: revert breaking changes relating to WorkspaceOwnerName (#18304)
Cherry-picks following commits:

*
https://github.com/coder/coder/commit/f974add3730452bcf242af55fd1c5fe68ffda77f
reverts
https://github.com/coder/coder/commit/d63417b5426fdfbb980e77aebb0d48fa535ababc
*
https://github.com/coder/coder/commit/d779126ee34720adc7af455a110d932a7facd268
reverts
https://github.com/coder/coder/commit/2ec74041970680b66564dbd79238b62502f61598

---------

Co-authored-by: Bruno Quaresma <bruno@coder.com>
2025-06-10 14:00:45 +01:00
Stephen Kirby 3a68676b84 chore: cherry-pick bug fixes for release 2.23 (#18219)
Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
Co-authored-by: Jaayden Halko <jaayden.halko@gmail.com>
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
2025-06-03 14:27:57 -05:00
gcp-cherry-pick-bot[bot] d3b6863ae9 docs: add link for Coder Desktop docs on workspace page (cherry-pick #18202) (#18204)
Co-authored-by: Atif Ali <atif@coder.com>
2025-06-03 19:19:35 +05:00
Jaayden Halko 2ded3b59e9 chore: remove beta badges (#18069) 2025-05-27 16:48:02 -04:00
Steven Masley b4531c4218 feat: make dynamic parameters respect owner in form (#18013)
Closes https://github.com/coder/coder/issues/18012

---------

Co-authored-by: Jaayden Halko <jaayden.halko@gmail.com>
2025-05-27 15:43:00 -05:00
Jaayden Halko 5b9c40481f feat: add form_type error (#18067)
Normally parameters had red text for error diagnostics. The goal here is
to make errors more obvious when the form_type is error meaning the
parameter could not be processed correctly.

<img width="543" alt="Screenshot 2025-05-27 at 18 35 50"
src="https://github.com/user-attachments/assets/2265553e-34a3-4526-8209-6253d541f784"
/>
2025-05-27 15:35:11 -04:00
ケイラ 9fc3329575 feat: persist app groups in the database (#17977) 2025-05-27 13:13:08 -06:00
Steven Masley 513a468a3a chore: disable logs sourced from dynamic params parsing (#18066)
Logs emitted by dynamic params did not have any additional scope or
context, and are not helpful in the current state. A future change can
capture these logs for display somewhere.

Does this by using latest `preview`
2025-05-27 17:39:44 +00:00
Mathias Fredriksson a18eb9d08f feat(site): allow recreating devcontainers and showing dirty status (#18049)
This change allows showing the devcontainer dirty status in the UI as
well as a recreate button to update the devcontainer.

Closes #16424
2025-05-27 19:42:24 +03:00
Jaayden Halko 23d14233bf chore: hide classic workspace checkbox when experiment is not enabled (#18061)
resolves coder/preview#137

This hides the `Use classic workspace creation form` checkbox on the
template settings page if the dynamic-parameters experiment is not
enabled

Add mention of "workspace parameters settings form" in the checkbox
description as this is also affected.
2025-05-27 12:02:54 -04:00
Zane 71a647b001 feat: support ConvertUserLoginType for another user in codersdk(#17784)
Added `ConvertUserLoginType(ctx, user, req)` method to support
converting the login type for a specified user.
2025-05-27 09:53:02 -05:00
Bruno Quaresma d63417b542 fix: update WorkspaceOwnerName to use user.name instead of user.username (#18025)
We have been using the user.username instead of user.name in wrong
places, making it very confusing for the UI.
2025-05-27 11:42:07 -03:00
Bruno Quaresma 9827c97f32 feat: add AI Tasks page (#18047)
**Preview:**

<img width="1624" alt="Screenshot 2025-05-26 at 21 25 04"
src="https://github.com/user-attachments/assets/2a51915d-2527-4467-bf99-1f2d876b953b"
/>
2025-05-27 11:34:07 -03:00
Cian Johnston ce134bc63a fix: handle invalid provisioning timings in ui (#18058)
Relates to https://github.com/coder/coder/issues/15432

* Adds a storybook entry for zero values in provisioner timings.
* Coerces a 'zero' start time to an 'instant'.
* Improves timing chart handling for large timeframes. Previously, this
would have caused the tab to run out of memory when encountering a
`time.Time{}`.
* Render 'instants' as 'invalid' in timing chart.
2025-05-27 15:10:57 +01:00
Susana Ferreira 565fad5951 chore: bump github.com/coder/terraform-provider-coder/v2 from 2.5.0 to 2.5.2 (#18054)
Bumps
[github.com/coder/terraform-provider-coder/v2](https://github.com/coder/terraform-provider-coder)
from 2.5.0 to 2.5.2.

Release:
https://github.com/coder/terraform-provider-coder/releases/tag/v2.5.2
2025-05-27 15:09:37 +01:00
Yevhenii Shcherbina e8c75eb1c3 fix: fix metric for hard-limited presets (#18045)
```
// Report a metric only if the preset uses the latest version of the template and the template is not deleted.
// This avoids conflicts between metrics from old and new template versions.
//
// NOTE: Multiple versions of a preset can exist with the same orgName, templateName, and presetName,
// because templates can have multiple versions — or deleted templates can share the same name.
//
// The safest approach is to report the metric only for the latest version of the preset.
// When a new template version is released, the metric for the new preset should overwrite
// the old value in Prometheus.
//
// However, there’s one edge case: if an admin creates a template, it becomes hard-limited,
// then deletes the template and never creates another with the same name,
// the old preset will continue to be reported as hard-limited —
// even though it’s deleted. This will persist until `coderd` is restarted.
```
2025-05-27 10:07:36 -04:00
Bruno Quaresma 5b90c69b90 chore: simplify workspace routing (#17981) 2025-05-27 11:05:47 -03:00
Edward Angert db806ae243 docs: move early access badge in dynamic parameters doc (#18009)
and md fix

this is basically a `hotfix`

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-27 15:17:49 +02:00
Susana Ferreira 8f44603d8a chore: update Terraform testdata by running generate.sh (#18044)
## Summary

This PR updates the terraform/testdata by running
`provisioner/terraform/testdata/generate.sh` script. These changes occur
from `terraform-provider-coder`
[v2.4.2](https://github.com/coder/terraform-provider-coder/releases/tag/v2.4.2)
and are associated to the introduction of a `api_key_scope` optional
field with a default value:
https://github.com/coder/terraform-provider-coder/pull/391

## Changes

* Run `provisioner/terraform/testdata/generate.sh` script.
* Update `resource_test.go` to include `api_key_scope`
2025-05-27 13:18:21 +01:00
Michael Suchacz 01d144c56e chore: update cursor icon to be an svg without binary data (#18051) 2025-05-27 14:15:33 +02:00
Spike Curtis 6c0bed0f53 chore: update to coder/quartz v0.2.0 (#18007)
Upgrade to coder/quartz v0.2.0 including fixing up a minor API breaking change.
2025-05-27 16:05:03 +04:00
Hugo Dutka 9ada1232f3 chore: make the $RUNNER_TEMP RAM disk bigger on Windows in CI (#18050) 2025-05-27 12:26:50 +02:00
Bruno Quaresma afaa20e166 chore: add proxy provider decorator for storybook (#18023) 2025-05-26 22:39:44 -03:00
dependabot[bot] f678f921db chore: bump undici from 6.21.1 to 6.21.2 in /site (#17856)
Bumps [undici](https://github.com/nodejs/undici) from 6.21.1 to 6.21.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nodejs/undici/releases">undici's
releases</a>.</em></p>
<blockquote>
<h2>v6.21.2</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(types): add missing DNS interceptor by <a
href="https://github.com/slagiewka"><code>@​slagiewka</code></a> in <a
href="https://redirect.github.com/nodejs/undici/pull/4024">nodejs/undici#4024</a></li>
<li>[v6.x] fix wpts on windows by <a
href="https://github.com/mcollina"><code>@​mcollina</code></a> in <a
href="https://redirect.github.com/nodejs/undici/pull/4093">nodejs/undici#4093</a></li>
<li>Removed clients with unrecoverable errors from the Pool <a
href="https://redirect.github.com/nodejs/undici/pull/4088">nodejs/undici#4088</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/slagiewka"><code>@​slagiewka</code></a>
made their first contribution in <a
href="https://redirect.github.com/nodejs/undici/pull/4024">nodejs/undici#4024</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/nodejs/undici/compare/v6.21.1...v6.21.2">https://github.com/nodejs/undici/compare/v6.21.1...v6.21.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nodejs/undici/commit/b63d939953fe20cfd6718e8eed437da983ac7b12"><code>b63d939</code></a>
Bumped v6.21.2</li>
<li><a
href="https://github.com/nodejs/undici/commit/de1e4b8a39d102bb34155c3fdec3f18806b93d9c"><code>de1e4b8</code></a>
[v6.x] fix wpts on windows (<a
href="https://redirect.github.com/nodejs/undici/issues/4093">#4093</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/4e07dda835ffb2ff7a1b1323dd94c61b8feaa3c5"><code>4e07dda</code></a>
test: fix windows wpt (<a
href="https://redirect.github.com/nodejs/undici/issues/4050">#4050</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/133387138c9158d3b6e9493833986c34837035ad"><code>1333871</code></a>
Removed clients with unrecoverable errors from the Pool (<a
href="https://redirect.github.com/nodejs/undici/issues/4088">#4088</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/a0e76c73a8ecb913beea7e2210e40d12b7c5cf69"><code>a0e76c7</code></a>
fix(types): add missing DNS interceptor (<a
href="https://redirect.github.com/nodejs/undici/issues/4024">#4024</a>)</li>
<li>See full diff in <a
href="https://github.com/nodejs/undici/compare/v6.21.1...v6.21.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=6.21.1&new-version=6.21.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-26 19:41:27 +00:00
Susana Ferreira 6f6e73af03 feat: implement expiration policy logic for prebuilds (#17996)
## Summary 

This PR introduces support for expiration policies in prebuilds. The TTL
(time-to-live) is retrieved from the Terraform configuration
([terraform-provider-coder
PR](https://github.com/coder/terraform-provider-coder/pull/404)):
```
prebuilds = {
	  instances = 2
	  expiration_policy {
		  ttl = 86400
	  }
  }
```
**Note**: Since there is no need for precise TTL enforcement down to the
second, in this implementation expired prebuilds are handled in a single
reconciliation cycle: they are deleted, and new instances are created
only if needed to match the desired count.

## Changes

* The outcome of a reconciliation cycle is now expressed as a slice of
reconciliation actions, instead of a single aggregated action.
* Adjusted reconciliation logic to delete expired prebuilds and
guarantee that the number of desired instances is correct.
* Updated relevant data structures and methods to support expiration
policies parameters.
* Added documentation to `Prebuilt workspaces` page
* Update `terraform-provider-coder` to version 2.5.0:
https://github.com/coder/terraform-provider-coder/releases/tag/v2.5.0

Depends on: https://github.com/coder/terraform-provider-coder/pull/404
Fixes: https://github.com/coder/coder/issues/17916
2025-05-26 20:31:24 +01:00
Bruno Quaresma 589f18627e chore: update vite deps and simplify config (#18036) 2025-05-26 16:29:36 -03:00
Bruno Quaresma c18169a402 chore: remove ts-prune (#18037)
We are using knip
2025-05-26 16:17:52 -03:00
Bruno Quaresma aec64e0c73 chore: remove unused exports (#18038) 2025-05-26 16:17:21 -03:00
Bruno Quaresma f3311400d1 chore: upgrade tanstack/react-query to 5.77.0 (#18039) 2025-05-26 16:16:55 -03:00
Yevhenii Shcherbina 2a15aa8a6f feat: add hard-limited presets metric (#18008)
Closes https://github.com/coder/coder/issues/17988

Define `preset_hard_limited` metric which for every preset indicates
whether a given preset has reached the hard failure limit (1 for
hard-limited, 0 otherwise).

CLI example:
```
curl -X GET localhost:2118/metrics | grep preset_hard_limited
# HELP coderd_prebuilt_workspaces_preset_hard_limited Indicates whether a given preset has reached the hard failure limit (1 for hard-limited, 0 otherwise).
# TYPE coderd_prebuilt_workspaces_preset_hard_limited gauge
coderd_prebuilt_workspaces_preset_hard_limited{organization_name="coder",preset_name="GoLand: Large",template_name="Test7"} 1
coderd_prebuilt_workspaces_preset_hard_limited{organization_name="coder",preset_name="GoLand: Large",template_name="ValidTemplate"} 0
coderd_prebuilt_workspaces_preset_hard_limited{organization_name="coder",preset_name="IU: Medium",template_name="Test7"} 1
coderd_prebuilt_workspaces_preset_hard_limited{organization_name="coder",preset_name="IU: Medium",template_name="ValidTemplate"} 0
coderd_prebuilt_workspaces_preset_hard_limited{organization_name="coder",preset_name="WS: Small",template_name="Test7"} 1
```

NOTE:
```go
if !ps.Preset.Deleted && ps.Preset.UsingActiveVersion {
	c.metrics.trackHardLimitedStatus(ps.Preset.OrganizationName, ps.Preset.TemplateName, ps.Preset.Name, ps.IsHardLimited)
}
```

Only active template version is tracked. If admin creates new template
version - old value of metric (for previous template version) will be
overwritten with new value of metric (for active template version).
Because `template_version` is not part of metric:
```go
labels = []string{"template_name", "preset_name", "organization_name"}
```

Implementation is similar to implementation of
`MetricResourceReplacementsCount` metric

---------

Co-authored-by: Susana Ferreira <ssncferreira@gmail.com>
2025-05-26 11:39:44 -04:00
Mathias Fredriksson 0731304905 feat(agent/agentcontainers): recreate devcontainers concurrently (#18042)
This change introduces a refactor of the devcontainers recreation logic
which is now handled asynchronously rather than being request scoped.
The response was consequently changed from "No Content" to "Accepted" to
reflect this.

A new `Status` field was introduced to the devcontainer struct which
replaces `Running` (bool). This reflects that the devcontainer can now
be in various states (starting, running, stopped or errored).

The status field also protects against multiple concurrent recrations,
as long as they are initiated via the API.

Updates #16424
2025-05-26 18:30:52 +03:00
dependabot[bot] 60fd03dca6 chore: bump github.com/mark3labs/mcp-go from 0.29.0 to 0.30.0 (#18041)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.29.0 to 0.30.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.30.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Feat: Impl Server-Side Streamable HTTP transport by <a
href="https://github.com/leavez"><code>@​leavez</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/273">mark3labs/mcp-go#273</a></li>
<li>Support customize request header by <a
href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/315">mark3labs/mcp-go#315</a></li>
<li>docs: add regeneration instructions by <a
href="https://github.com/pmenglund"><code>@​pmenglund</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/309">mark3labs/mcp-go#309</a></li>
<li>docs(examples): correct use of <code>GetArguments</code> by <a
href="https://github.com/jamietanna"><code>@​jamietanna</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/316">mark3labs/mcp-go#316</a></li>
<li>fix: avoid painc caused by writing to closed channel by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/318">mark3labs/mcp-go#318</a></li>
<li>docs: use helper functions and return error as result by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/322">mark3labs/mcp-go#322</a></li>
<li>Update README.md by <a
href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/323">mark3labs/mcp-go#323</a></li>
<li>Feat(prompts): add DeletePrompts method to MCPServer by <a
href="https://github.com/God-Jay"><code>@​God-Jay</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/320">mark3labs/mcp-go#320</a></li>
<li>Scaffold documentation site by <a
href="https://github.com/ezynda3"><code>@​ezynda3</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/324">mark3labs/mcp-go#324</a></li>
<li>Docs by <a
href="https://github.com/ezynda3"><code>@​ezynda3</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/325">mark3labs/mcp-go#325</a></li>
<li>feat: Implement OAuth in the client by <a
href="https://github.com/ezynda3"><code>@​ezynda3</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/296">mark3labs/mcp-go#296</a></li>
<li>feat(server): persist client info in sessions by <a
href="https://github.com/ShawkyZ"><code>@​ShawkyZ</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/313">mark3labs/mcp-go#313</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/pmenglund"><code>@​pmenglund</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/309">mark3labs/mcp-go#309</a></li>
<li><a
href="https://github.com/jamietanna"><code>@​jamietanna</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/316">mark3labs/mcp-go#316</a></li>
<li><a href="https://github.com/God-Jay"><code>@​God-Jay</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/320">mark3labs/mcp-go#320</a></li>
<li><a href="https://github.com/ShawkyZ"><code>@​ShawkyZ</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/313">mark3labs/mcp-go#313</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.29.0...v0.30.0">https://github.com/mark3labs/mcp-go/compare/v0.29.0...v0.30.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/9e6ccca8025f3b63533540ac91fd06cc3dc10401"><code>9e6ccca</code></a>
Formatting</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/2c8bf2bb750186c656161107b2e5e1198aa53539"><code>2c8bf2b</code></a>
feat(server): persist client info in sessions (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/313">#313</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/0c3f53507f746dd02434d8d159a7f711240962e8"><code>0c3f535</code></a>
feat: Implement OAuth in the client (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/296">#296</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/617c67623617e91f17263346d267cda064524102"><code>617c676</code></a>
update</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/5a1d3fe0ed0e26e71ff6ecdce9b5b156dec79b88"><code>5a1d3fe</code></a>
add basePath</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/76f698504f02b9013aafb48e13ec816af55c185c"><code>76f6985</code></a>
add baseUrl</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/f1015695362a5842a1bd9e4a86770f2b0d59ef56"><code>f101569</code></a>
Docs (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/325">#325</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/563a9c74e55f31ad060f7cf8d5cec778e1c37c8a"><code>563a9c7</code></a>
Scaffold documentation site (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/324">#324</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/820b7a68b8c98447a041654fbe2e0910fad3ec6e"><code>820b7a6</code></a>
Feat(prompts): add DeletePrompts method to MCPServer (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/320">#320</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/3cdeb8919f3140319b743f39be43666208008d17"><code>3cdeb89</code></a>
Update README.md (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/323">#323</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.29.0...v0.30.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.29.0&new-version=0.30.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-26 11:45:32 +00:00
dependabot[bot] d01406fa7e chore: bump github.com/coder/terraform-provider-coder/v2 from 2.4.2 to 2.5.0 (#18040)
Bumps
[github.com/coder/terraform-provider-coder/v2](https://github.com/coder/terraform-provider-coder)
from 2.4.2 to 2.5.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/coder/terraform-provider-coder/releases">github.com/coder/terraform-provider-coder/v2's
releases</a>.</em></p>
<blockquote>
<h2>v2.5.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: allow dropdown form_type for boolean types by <a
href="https://github.com/Emyrk"><code>@​Emyrk</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/397">coder/terraform-provider-coder#397</a></li>
<li>build(deps): Bump github.com/hashicorp/terraform-plugin-sdk/v2 from
2.36.1 to 2.37.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/400">coder/terraform-provider-coder#400</a></li>
<li>fix: map_structure of form_type to match argument name by <a
href="https://github.com/Emyrk"><code>@​Emyrk</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/401">coder/terraform-provider-coder#401</a></li>
<li>docs: update README note for local provider testing with correct
module path by <a
href="https://github.com/ssncferreira"><code>@​ssncferreira</code></a>
in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/403">coder/terraform-provider-coder#403</a></li>
<li>feat: add <code>group</code> attribute to <code>coder_app</code>
resource by <a
href="https://github.com/aslilac"><code>@​aslilac</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/402">coder/terraform-provider-coder#402</a></li>
<li>feat: add expiration_policy parameter to prebuild resource by <a
href="https://github.com/ssncferreira"><code>@​ssncferreira</code></a>
in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/404">coder/terraform-provider-coder#404</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/ssncferreira"><code>@​ssncferreira</code></a>
made their first contribution in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/403">coder/terraform-provider-coder#403</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/coder/terraform-provider-coder/compare/v2.4.2...v2.5.0">https://github.com/coder/terraform-provider-coder/compare/v2.4.2...v2.5.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/28dae7fbc263efcaaa33f5ec448004fa47109858"><code>28dae7f</code></a>
feat: add expiration_policy parameter to prebuild resource (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/404">#404</a>)</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/74899537ddc92f178bb9129645649889f8e0af32"><code>7489953</code></a>
feat: add <code>group</code> attribute to <code>coder_app</code>
resource (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/402">#402</a>)</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/0c7fd6a3950b2195043df792087d6a33b4e14369"><code>0c7fd6a</code></a>
docs: update README note for local provider testing with correct module
path ...</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/a4f40659a9be991eaaa6d833781fbdb942c2e308"><code>a4f4065</code></a>
fix: map_structure of form_type to match argument name (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/401">#401</a>)</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/77de38e09cca9ca228b63bb53f32ba0ae75a1f2d"><code>77de38e</code></a>
build(deps): Bump github.com/hashicorp/terraform-plugin-sdk/v2 (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/400">#400</a>)</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/ace4462675ffbab17e098dff330ce50ece20b7fe"><code>ace4462</code></a>
fix: allow dropdown form_type for boolean types (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/397">#397</a>)</li>
<li>See full diff in <a
href="https://github.com/coder/terraform-provider-coder/compare/v2.4.2...v2.5.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/coder/terraform-provider-coder/v2&package-manager=go_modules&previous-version=2.4.2&new-version=2.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-26 11:41:54 +00:00
Bruno Quaresma 5cdda2ea7d chore: replace date-fns by dayjs (#18022)
This change replaces date-fns with dayjs throughout the codebase for
more consistent date/time handling and to reduce bundle size. It also
tries to make the formatting and usage consistent.

**Why dayjs over date-fns?**
Just because we were using dayjs more broadly. Its formatting
capabilities, were also easier to extend.
2025-05-25 00:32:36 -03:00
dependabot[bot] a605c09d2b ci: bump the github-actions group with 2 updates (#18035)
Bumps the github-actions group with 2 updates:
[chromaui/action](https://github.com/chromaui/action) and
[tj-actions/changed-files](https://github.com/tj-actions/changed-files).

Updates `chromaui/action` from 11.29.0 to 12.0.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/chromaui/action/commit/d7afd50124cf4f337bcd943e7f45cfa85a5e4476"><code>d7afd50</code></a>
v12.0.0</li>
<li>See full diff in <a
href="https://github.com/chromaui/action/compare/1cfa065cbdab28f6ca3afaeb3d761383076a35aa...d7afd50124cf4f337bcd943e7f45cfa85a5e4476">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/changed-files` from
480f49412651059a414a6a5c96887abb1877de8a to
3981e4f74104e7a4c67a835e1e5dd5d9eb0f0a57
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/changed-files/blob/main/HISTORY.md">tj-actions/changed-files's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.4...v46.0.5">46.0.5</a>
- (2025-04-09)</h1>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li><strong>deps:</strong> Bump yaml from 2.7.0 to 2.7.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2520">#2520</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/ed68ef82c095e0d48ec87eccea555d944a631a4c">ed68ef8</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump typescript from 5.8.2 to 5.8.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2516">#2516</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/a7bc14b808f23d3b467a4079c69a81f1a4500fd5">a7bc14b</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump <code>@​types/node</code> from
22.13.11 to 22.14.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2517">#2517</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/3d751f6b6d84071a17e1b9cf4ed79a80a27dd0ab">3d751f6</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump eslint-plugin-prettier from 5.2.3 to
5.2.6 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2519">#2519</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/e2fda4ec3cb0bc2a353843cae823430b3124db8f">e2fda4e</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump ts-jest from 29.2.6 to 29.3.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2518">#2518</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/0bed1b1132ec4879a39a2d624cf82a00d0bcfa48">0bed1b1</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump github/codeql-action from 3.28.12 to
3.28.15 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2530">#2530</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/68024587dc36f49685c96d59d3f1081830f968bb">6802458</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/branch-names from 8.0.1 to
8.1.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2521">#2521</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/cf2e39e86bf842d1f9bc5bca56c0a6b207cca792">cf2e39e</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/verify-changed-files from
20.0.1 to 20.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2523">#2523</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6abeaa506a419f85fa9e681260b443adbeebb3d4">6abeaa5</a>)
- (dependabot[bot])</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2511">#2511</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/6f67ee9ac810f0192ea7b3d2086406f97847bcf9">6f67ee9</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.3...v46.0.4">46.0.4</a>
- (2025-04-03)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li>Bug modified_keys and changed_key outputs not set when no changes
detected (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2509">#2509</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6cb76d07bee4c9772c6882c06c37837bf82a04d3">6cb76d0</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<ul>
<li>Update readme (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2508">#2508</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/b74df86ccb65173a8e33ba5492ac1a2ca6b216fd">b74df86</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2506">#2506</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted -->
Co-authored-by: Tonye Jack <a
href="mailto:jtonye@ymail.com">jtonye@ymail.com</a> (<a
href="https://github.com/tj-actions/changed-files/commit/27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99">27ae6b3</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.2...v46.0.3">46.0.3</a>
- (2025-03-23)</h1>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2501">#2501</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/41e0de576a0f2b64d9f06f2773f539109e55a70a">41e0de5</a>)
- (github-actions[bot])</p>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2499">#2499</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/945787811a795cd840a1157ac590dd7827a05c8e">9457878</a>)
- (github-actions[bot])</p>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/changed-files/commit/3981e4f74104e7a4c67a835e1e5dd5d9eb0f0a57"><code>3981e4f</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.15.17 to
22.15.21 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2566">#2566</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/403a8a6fd188648f8a5adab2047d8eab5c0a4b34"><code>403a8a6</code></a>
chore(deps-dev): bump ts-jest from 29.3.2 to 29.3.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2563">#2563</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/5c5e8c9b886c1ff1c08a9df23b1ee6e0c0d44001"><code>5c5e8c9</code></a>
chore(deps): bump yaml from 2.7.1 to 2.8.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2561">#2561</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/d869acea438612407cf27745d747734afb0140db"><code>d869ace</code></a>
chore(deps-dev): bump <code>@​types/lodash</code> from 4.17.16 to
4.17.17 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2565">#2565</a>)</li>
<li>See full diff in <a
href="https://github.com/tj-actions/changed-files/compare/480f49412651059a414a6a5c96887abb1877de8a...3981e4f74104e7a4c67a835e1e5dd5d9eb0f0a57">compare
view</a></li>
</ul>
</details>
<br />

<details>
<summary>Most Recent Ignore Conditions Applied to This Pull
Request</summary>

| Dependency Name | Ignore Conditions |
| --- | --- |
| chromaui/action | [>= 11.a, < 12] |
</details>


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-24 22:25:19 +00:00
dependabot[bot] 62a5c4c3d7 chore: bump github.com/mark3labs/mcp-go from 0.28.0 to 0.29.0 (#18031)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.28.0 to 0.29.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.29.0</h2>
<h2>What's Changed</h2>
<ul>
<li>refactor: make CallToolRequest.Arguments more flexible (Breaking
Change) by <a
href="https://github.com/ezynda3"><code>@​ezynda3</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/287">mark3labs/mcp-go#287</a></li>
<li>Drop unused fields from server.sseSession by <a
href="https://github.com/ggoodman"><code>@​ggoodman</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/303">mark3labs/mcp-go#303</a></li>
<li>chore: remove unused variables and type arguments by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/302">mark3labs/mcp-go#302</a></li>
<li>chore(Srv/stdio): duplicated setting of ErrorLogger by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/306">mark3labs/mcp-go#306</a></li>
<li>fix: handle the situation where the channel is closed by <a
href="https://github.com/button-chen"><code>@​button-chen</code></a> in
<a
href="https://redirect.github.com/mark3labs/mcp-go/pull/304">mark3labs/mcp-go#304</a></li>
</ul>
<h2>Breaking Changes</h2>
<p>In <code>v0.29.0</code>, MCP-Go introduces breaking changes to tool
request handling. The main change is that
<code>request.Params.Arguments</code> is no longer directly accessible
as a map. Instead, you must use the new <code>GetArguments()</code>
method to retrieve arguments as a map. For type-safe argument access,
new helper methods like <code>RequireString()</code>,
<code>RequireFloat()</code>, and <code>RequireBool()</code> have been
added. To migrate:</p>
<ol>
<li>Replace direct access to
<code>request.Params.Arguments[&quot;key&quot;]</code> with
<code>request.GetArguments()[&quot;key&quot;]</code></li>
<li>For better type safety, use the new helper methods:
<code>request.RequireString(&quot;key&quot;)</code>,
<code>request.RequireFloat(&quot;key&quot;)</code>, etc.</li>
<li>For complex argument structures, use the new
<code>BindArguments()</code> method with a struct, or try the new typed
tool handlers with <code>mcp.NewTypedToolHandler()</code> as shown in
the new <code>examples/typed_tools</code> example.</li>
</ol>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/ggoodman"><code>@​ggoodman</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/303">mark3labs/mcp-go#303</a></li>
<li><a
href="https://github.com/button-chen"><code>@​button-chen</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/304">mark3labs/mcp-go#304</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.28.0...v0.29.0">https://github.com/mark3labs/mcp-go/compare/v0.28.0...v0.29.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/99720bb4c4513ba1d2443b4e5045b7763e0b7142"><code>99720bb</code></a>
fix: handle the situation where the channel is closed (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/304">#304</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/420d52199bb3557fe4bd0f5b5aa07c3e3721ae7b"><code>420d521</code></a>
chore(Srv/stdio): duplicated setting of ErrorLogger (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/306">#306</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/eaa6f29a3b0776e17c7cdc455eeccc9be72b473a"><code>eaa6f29</code></a>
chore: remove unused variables and type arguments (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/302">#302</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/65010c4c5c167e8fa6ca1e4fd242de04027567ce"><code>65010c4</code></a>
chore: drop unused fields from sseSession (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/303">#303</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/28c9cc310fed16014107a4e4c970b1d440066b4a"><code>28c9cc3</code></a>
refactor: make CallToolRequest.Arguments more flexible (Breaking Change)
(<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/287">#287</a>)</li>
<li>See full diff in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.28.0...v0.29.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.28.0&new-version=0.29.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-24 22:23:15 +00:00
Atif Ali 5827219812 chore: update module sources in templates to new format (#18026) 2025-05-25 00:15:18 +02:00
Atif Ali 24d68be58b chore: enable dependabot for terraform modules (#18028)
#18027 got merged to the wrong branch
2025-05-24 22:06:55 +00:00
Bruno Quaresma 70edc2403a chore: remove chartjs (#18016)
- Remove ChartJS in favor of Recharts
- Migrate ActiveUserChart to use the new chart design

<img width="1624" alt="Screenshot 2025-05-23 at 15 00 03"
src="https://github.com/user-attachments/assets/5f451a88-f2ef-4139-a888-c0358eb8cf17"
/>
2025-05-24 11:33:16 -03:00
Jaayden Halko 196eccb457 feat: add beta labels for dynamic params (#17985)
<img width="820" alt="Screenshot 2025-05-23 at 18 48 56"
src="https://github.com/user-attachments/assets/5b781501-3817-4be1-8143-f03f8cb88901"
/>

<img width="790" alt="Screenshot 2025-05-23 at 18 48 32"
src="https://github.com/user-attachments/assets/541ad77e-fd37-4f52-ae2c-7b1f698c23fc"
/>
2025-05-23 15:51:31 -04:00
Jaayden Halko ce4c8c7451 fix: prevent layout shift when Select component dropdown appears (#17990)
When scrollbars are always visible, open the dropdown for a `Select
`component causes a layout shift because of scrollbars being hidden when
the` Select` is open. This fix prevents the layout shift from the
scrollbar being removed.




https://github.com/user-attachments/assets/6b0aff70-c585-401b-911d-f0805b54903e
2025-05-23 15:51:14 -04:00
Bruno Quaresma e8306cc790 chore: improve chromatic CI (#18014)
Following [this Chromatic
guide](https://www.chromatic.com/docs/turbosnap-best-practices) to
improve our Chromatic jobs.
2025-05-23 15:10:06 -03:00
Steven Masley ca39931395 chore: remove password form_type from docs (#18015) 2025-05-23 12:17:22 -05:00
Jaayden Halko 516fb4489e feat: display required badge instead of diagnostic text when extra code = required (#18006)
The tooltip hover uses the summary text from the diagnostic

<img width="562" alt="Screenshot 2025-05-23 at 12 51 51"
src="https://github.com/user-attachments/assets/2246abc7-dc1c-4dc2-8303-bee62d152e21"
/>
2025-05-23 10:43:17 -04:00
Bruno Quaresma 30a910ba32 chore: replace MUI Button - 2 (#17953)
1. IconField.tsx
2. SelectMenu.tsx
3. RichParameterInput.tsx
4. MissingTemplateVariablesDialog.tsx
5. LoginPageView.tsx
2025-05-23 11:39:56 -03:00
Bruno Quaresma 94c129c03d fix!: omit name, avatar_url and last_seen_at from responses when empty (#18005)
User name, avatar URL, and last seen at, are not required fields so they
can be empty. Instead of returning the 0 values from Go, we want to make
it more agnostic, and omit them when they are empty. This make the docs
and usage way clearer for consumers.
2025-05-23 11:35:05 -03:00
Ethan 96f69b8e13 chore: set slim tag when compiling coder-vpn.dylib (#18001)
```
$ du -sh before.dylib after.dylib 
 35M    before.dylib
 30M    after.dylib
 ```
2025-05-23 15:03:09 +10:00
Bruno Quaresma b4daf36d0b refactor: refactor activity column in the workspaces table (#17976)
The goal is to better integrate the activity column data with the
existent data:
- Make the message one line, the full message is in the tooltip, and
display the state at the bottom. This way, it is visually consistent
with the other columns like status, name and template.
- Moved the app, and uri, to the actions column, instead of showing them
together with the message in the activity column.

**Previous:**
<img width="1512" alt="Screenshot 2025-05-21 at 17 28 46"
src="https://github.com/user-attachments/assets/ea9188a5-d82e-416c-b961-edf0104f66c6"
/>

**After:**
<img width="1512" alt="Screenshot 2025-05-21 at 17 28 57"
src="https://github.com/user-attachments/assets/f50dbe82-cd3e-4448-9fa2-bde9193166d6"
/>
2025-05-22 20:03:13 -04:00
Kris Page c777740801 docs: add Bottlerocket section to rootless Podman (#17987) 2025-05-22 21:12:31 +01:00
Mathias Fredriksson d6c14f3d8a feat(agent/agentcontainers): update containers periodically (#17972)
This change introduces a significant refactor to the agentcontainers API
and enables periodic updates of Docker containers rather than on-demand.
Consequently this change also allows us to move away from using a
locking channel and replace it with a mutex, which simplifies usage.

Additionally a previous oversight was fixed, and testing added, to clear
devcontainer running/dirty status when the container has been removed.

Updates coder/coder#16424
Updates coder/internal#621
2025-05-22 19:44:33 +03:00
Steven Masley 13b41c200c chore: update preview to include required param diags (#17978) 2025-05-22 11:40:21 -05:00
Bruno Quaresma 6f0defb2c9 refactor: refactor activity in workspace page (#17980)
Changing the activity in the workspace page. It is more boring, but more
reliable and extensible. By moving it to the bottom of the agent card,
we have more space to display longer messages and more items. It also
give us some space for interactivity controls in case we want them in
the future.

**Before:**
<img width="1512" alt="Screenshot 2025-05-21 at 19 09 41"
src="https://github.com/user-attachments/assets/c25aa848-b496-4a78-8d19-0b0efeae6115"
/>

**After:**


https://github.com/user-attachments/assets/3e88eb63-e082-4e5c-a6a3-79a6fe3d46b6
2025-05-22 13:05:51 -03:00
Atif Ali 4cb35c4c65 docs: fix token create command (#17984)
`--name` is required
2025-05-22 10:39:51 -04:00
Hugo Dutka a0e229afec chore: run test-go-pg on macOS and Windows in regular CI (#17853)
This PR starts running test-go-pg on macOS and Windows in regular CI.
Previously this suite was only run in the nightly gauntlet for 2
reasons:

- it was flaky
- it was slow (took 17 minutes)

We've since stabilized the flakiness by switching to depot runners,
using ram disks, optimizing the number of tests run in parallel, and
automatically re-running failing tests. We've also [brought
down](https://github.com/coder/coder/pull/17756) the time to run the
suite to 9 minutes. Additionally, this PR allows test-go-pg to use cache
from previous runs, which speeds it up further. The cache is only used
on PRs, `main` will still run tests without it.

This PR also:

- removes the nightly gauntlet since all tests now run in regular CI
- removes the `test-cli` job for the same reason
- removes the `setup-imdisk` action which is now fully replaced by
[coder/setup-ramdisk-action](https://github.com/coder/setup-ramdisk-action)
- makes 2 minor changes which could be separate PRs, but I rolled them
into this because they were helpful when iterating on it:
- replace the `if: always()` condition on the `gen` job with a `if: ${{
!cancelled() }}` to allow the job to be cancelled. Previously the job
would run to completion even if the entire workflow was cancelled. See
[the GitHub
docs](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#always)
for more details.
- disable the recently added `TestReinitializeAgent` since it does not
pass on Windows with Postgres. There's an open issue to fix it:
https://github.com/coder/internal/issues/642

This PR will:

- unblock https://github.com/coder/coder/issues/15109
- alleviate https://github.com/coder/internal/issues/647

I tested caching by temporarily enabling cache upload on this PR: here's
[a
run](https://github.com/coder/coder/actions/runs/15119046903/job/42496939341?pr=17853#step:13:1296)
showing cache being used.
2025-05-22 15:53:37 +02:00
Hugo Dutka f825477a5c fix: add timeouts to test telemetry snapshot (#17879)
This PR ensures that waits on channels will time out according to the
test context, rather than waiting indefinitely. This should alleviate
the panic seen in https://github.com/coder/internal/issues/645 and, if
the deadlock recurs, allow the test to be retried automatically in CI.
2025-05-22 13:51:24 +02:00
Atif Ali 5a3a7fc4e5 chore: add JetBrains Toolbox to docs manifest (#17986) 2025-05-22 16:30:56 +05:00
Edward Angert eb8013a7f4 docs: add jetbrains toolbox steps (#17661)
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: ケイラ <mckayla@hey.com>
Co-authored-by: Jon Ayers <jon@coder.com>
Co-authored-by: Danny Kopping <danny@coder.com>
Co-authored-by: Michael Suchacz <203725896+ibetitsmike@users.noreply.github.com>
Co-authored-by: Bruno Quaresma <bruno@coder.com>
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
Co-authored-by: Atif Ali <atif@coder.com>
2025-05-22 16:08:59 +05:00
Ethan 34494fb330 chore: avoid depending on rbac in slim builds (#17959)
I noticed the `coder-vpn.dylib` (of course alongside the Agent/CLI binaries) had grown substantially (from 29MB to 37MB for the dylib), and discovered that importing RBAC in slim builds was the issue

This PR removes the dependency on RBAC in slim builds, and adds a compile-time check to ensure it can't be imported in the future:

```
$ make build
# github.com/coder/coder/v2/coderd/rbac
coderd/rbac/no_slim.go:8:2: initialization cycle: _DO_NOT_IMPORT_THIS_PACKAGE_IN_SLIM_BUILDS refers to itself
make: *** [Makefile:224: build/coder-slim_2.22.1-devel+7e46d24b4_linux_amd64] Error 1
```

Before and after for `coder-slim_darwin_arm64`:
```
$ gsa before after
┌───────────────────────────────────────────────────────────────────────────────────┐
│ Diff between before and after                                                     │
├─────────┬─────────────────────────────────────────┬──────────┬──────────┬─────────┤
│ PERCENT │ NAME                                    │ OLD SIZE │ NEW SIZE │ DIFF    │
├─────────┼─────────────────────────────────────────┼──────────┼──────────┼─────────┤
│ -100%   │ github.com/gorilla/mux                  │          │          │ +0 B    │
│ -100%   │ github.com/ammario/tlru                 │          │          │ +0 B    │
│ -100%   │ github.com/armon/go-radix               │          │          │ +0 B    │
│ -0.00%  │ gvisor.dev/gvisor                       │ 2.4 MB   │ 2.4 MB   │ -4 B    │
│ -0.21%  │ os                                      │ 155 kB   │ 155 kB   │ -328 B  │
│ -0.23%  │ regexp                                  │ 152 kB   │ 152 kB   │ -346 B  │
│ -0.04%  │ runtime                                 │ 876 kB   │ 876 kB   │ -372 B  │
│ -100%   │ github.com/rcrowley/go-metrics          │ 675 B    │          │ -675 B  │
│ -23.79% │ github.com/cespare/xxhash/v2            │ 3.0 kB   │ 2.3 kB   │ -715 B  │
│ -100%   │ github.com/agnivade/levenshtein         │ 1.4 kB   │          │ -1.4 kB │
│ -100%   │ github.com/go-ini/ini                   │ 1.5 kB   │          │ -1.5 kB │
│ -100%   │ github.com/xeipuuv/gojsonreference      │ 2.4 kB   │          │ -2.4 kB │
│ -100%   │ github.com/xeipuuv/gojsonpointer        │ 5.2 kB   │          │ -5.2 kB │
│ -2.43%  │ go.opentelemetry.io/otel                │ 316 kB   │ 309 kB   │ -7.7 kB │
│ -2.40%  │ slices                                  │ 381 kB   │ 372 kB   │ -9.2 kB │
│ -0.68%  │ crypto                                  │ 1.4 MB   │ 1.4 MB   │ -9.5 kB │
│ -100%   │ github.com/tchap/go-patricia/v2         │ 23 kB    │          │ -23 kB  │
│ -100%   │ github.com/yashtewari/glob-intersection │ 28 kB    │          │ -28 kB  │
│ -4.35%  │ <autogenerated>                         │ 754 kB   │ 721 kB   │ -33 kB  │
│ -100%   │ github.com/sirupsen/logrus              │ 72 kB    │          │ -72 kB  │
│ -2.56%  │ github.com/coder/coder/v2               │ 3.3 MB   │ 3.2 MB   │ -84 kB  │
│ -100%   │ github.com/gobwas/glob                  │ 107 kB   │          │ -107 kB │
│ -100%   │ sigs.k8s.io/yaml                        │ 244 kB   │          │ -244 kB │
│ -100%   │ github.com/open-policy-agent/opa        │ 2.2 MB   │          │ -2.2 MB │
├─────────┼─────────────────────────────────────────┼──────────┼──────────┼─────────┤
│ -7.79%  │ __go_buildinfo __DATA                   │ 18 kB    │ 17 kB    │ -1.4 kB │
│ -6.81%  │ __itablink __DATA_CONST                 │ 23 kB    │ 22 kB    │ -1.6 kB │
│ -6.61%  │ __typelink __DATA_CONST                 │ 71 kB    │ 66 kB    │ -4.7 kB │
│ -2.86%  │ __noptrdata __DATA                      │ 1.0 MB   │ 993 kB   │ -29 kB  │
│ -21.49% │ __data __DATA                           │ 320 kB   │ 251 kB   │ -69 kB  │
│ -6.19%  │ __rodata __DATA_CONST                   │ 6.0 MB   │ 5.6 MB   │ -372 kB │
│ -47.19% │ __rodata __TEXT                         │ 7.6 MB   │ 4.0 MB   │ -3.6 MB │
├─────────┼─────────────────────────────────────────┼──────────┼──────────┼─────────┤
│ -14.02% │ before                                  │ 50 MB    │ 43 MB    │ -7.0 MB │
│         │ after                                   │          │          │         │
└─────────┴─────────────────────────────────────────┴──────────┴──────────┴─────────┘
```
2025-05-22 19:48:23 +10:00
Sas Swart 1e1e6f3bd1 fix: skip TestReinitializeAgent until we can adapt it for windows (#17968)
relates to https://github.com/coder/internal/issues/642

I've reached a timebox trying to get a script for windows to work, so
I'm skipping it for now.
2025-05-22 08:48:40 +02:00
Ben Potter a5234bf9a5 chore: fix autoversion script and update experiments/docs to v2.22.1 (#17954) 2025-05-21 23:17:14 -04:00
Yevhenii Shcherbina 53e8e9c7cd fix: reduce cost of prebuild failure (#17697)
Relates to https://github.com/coder/coder/issues/17432

### Part 1:

Notes:
- `GetPresetsAtFailureLimit` SQL query is added, which is similar to
`GetPresetsBackoff`, they use same CTEs: `filtered_builds`,
`time_sorted_builds`, but they are still different.

- Query is executed on every loop iteration. We can consider marking
specific preset as permanently failed as an optimization to avoid
executing query on every loop iteration. But I decided don't do it for
now.

- By default `FailureHardLimit` is set to 3.

- `FailureHardLimit` is configurable. Setting it to zero - means that
hard limit is disabled.

### Part 2

Notes:
- `PrebuildFailureLimitReached` notification is added.
- Notification is sent to template admins.
- Notification is sent only the first time, when hard limit is reached.
But it will `log.Warn` on every loop iteration.
- I introduced this enum:
```sql
CREATE TYPE prebuild_status AS ENUM (
  'normal',           -- Prebuilds are working as expected; this is the default, healthy state.
  'hard_limited',     -- Prebuilds have failed repeatedly and hit the configured hard failure limit; won't be retried anymore.
  'validation_failed' -- Prebuilds failed due to a non-retryable validation error (e.g. template misconfiguration); won't be retried.
);
```
`validation_failed` not used in this PR, but I think it will be used in
next one, so I wanted to save us an extra migration.

- Notification looks like this:
<img width="472" alt="image"
src="https://github.com/user-attachments/assets/e10efea0-1790-4e7f-a65c-f94c40fced27"
/>

### Latest notification views:
<img width="463" alt="image"
src="https://github.com/user-attachments/assets/11310c58-68d1-4075-a497-f76d854633fe"
/>
<img width="725" alt="image"
src="https://github.com/user-attachments/assets/6bbfe21a-91ac-47c3-a9d1-21807bb0c53a"
/>
2025-05-21 15:16:38 -04:00
Bruno Quaresma e1934fe119 chore: replace MUI icons with Lucide icons - update 18 (#17958)
1. PersonOutline → UserIcon
2. Apps → LayoutGridIcon
3. Delete → TrashIcon
4. InsertDriveFile → FileIcon
2025-05-21 16:11:23 -03:00
Bruno Quaresma f35a1bc448 chore: replace MUI Button - 3 (#17955)
Replaced MUI Button with custom Button in 5 components:
  - Filter.tsx - Changed import and updated Button props
(variant="outline", size="sm")
  - ChatLayout.tsx - Changed import and updated Button
props for the "New Chat" button
  - StarterTemplatePageView.tsx - Changed import and
implemented asChild pattern for links
  - Notifications.tsx - Changed import and updated
NotificationActionButton to use variant="subtle"
  - DateRange.tsx - Changed import and updated Button
styling
2025-05-21 15:58:38 -03:00
Bruno Quaresma cbfe975cc8 refactor: show unhealthy status on workspace status indicator (#17956)
Instead of showing a "yellow question icon" on the side of the status,
to let the user aware of unhealthy agents, we could make it yellow and
use a tooltip.

Before:
<img width="1512" alt="Screenshot 2025-05-20 at 18 13 15"
src="https://github.com/user-attachments/assets/afee470e-9dd4-4c32-b2bc-b9f66eac60fa"
/>

After:
<img width="1512" alt="Screenshot 2025-05-20 at 18 13 26"
src="https://github.com/user-attachments/assets/5769828b-f23c-45a5-8017-c4a88f085d0f"
/>
2025-05-21 15:57:32 -03:00
Jaayden Halko cb7ce18592 feat: add experimental workspace parameters page for dynamic params (#17841)
![Screenshot 2025-05-20 at 22 26
40](https://github.com/user-attachments/assets/639441d7-2349-4c92-a4ee-d8a5a724fe8e)
2025-05-21 13:48:35 -04:00
Jaayden Halko 3a6d5f5bba fix: update textarea to fit content height and set a max height (#17946) 2025-05-21 10:56:01 -04:00
Jaayden Halko 36d938fa88 fix: show diagnostics if there are no parameters (#17967)
Prefer to show the top level diagnostics inside the parameters section
for context but this adds a case to show diagnostics if there are no
parameters.

Normally, the entire parameters section is hidden if there are no
parameters.
2025-05-21 10:55:37 -04:00
Michael Suchacz b7462fb256 feat: improve transaction safety in CompleteJob function (#17970)
This PR refactors the CompleteJob function to use database transactions
more consistently for better atomicity guarantees. The large function
was broken down into three specialized handlers:

- completeTemplateImportJob
- completeWorkspaceBuildJob
- completeTemplateDryRunJob

Each handler now uses the Database.InTx wrapper to ensure all database
operations for a job completion are performed within a single
transaction, preventing partial updates in case of failures.

Added comprehensive tests for transaction behavior for each job type.

Fixes #17694

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-05-21 16:48:51 +02:00
Bruno Quaresma c6bece0ec5 refactor: update provisioners column copy (#17949) 2025-05-21 08:57:15 -03:00
Spike Curtis 818d4d03f4 chore: ignore 'session shutdown' yamux error in tests (#17964)
Fixes flake seen here: https://github.com/coder/coder/actions/runs/15154327939/job/42606133069?pr=17960

Error log dropped when the dRPC server is being shut down right as we are (re)dialing.
2025-05-21 11:29:25 +04:00
Michael Suchacz 3654a49fb5 feat: add Claude.md initial draft (#17785) 2025-05-21 09:16:00 +02:00
Spike Curtis cbbbb4492a docs: explain coder:// link for RDP (#17901)
fixes https://github.com/coder/internal/issues/627

Adds docs for `coder://` URLs for Windows Remote Desktop (RDP).

Note that we might want to hold of merging since the URI handling is
unreleased in Coder Desktop for Windows.
2025-05-21 09:28:31 +04:00
Bruno Quaresma 36224f263f chore: replace MUI icons with Lucide icons - 17 (#17957)
1. ExpandMoreOutlined → ChevronDownIcon
2. Error/ErrorIcon → CircleAlertIcon
3. CheckCircle → CircleCheckIcon
4. Warning → TriangleAlertIcon
2025-05-20 22:24:17 -03:00
Danielle Maywood 3e7ff9d9e1 chore(coderd/rbac): add Action{Create,Delete}Agent to ResourceWorkspace (#17932) 2025-05-20 21:20:56 +01:00
Danny Kopping d2d21898f2 chore: reduce ignore_changes suggestion scope (#17947)
We probably shouldn't be suggesting `ignore_changes = all`. Only the
attributes which cause drift in prebuilds should be ignored; everything
else can behave as normal.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Edward Angert <EdwardAngert@users.noreply.github.com>
2025-05-20 22:16:23 +02:00
Edward Angert 1f54c36375 docs: rename external-auth heading in setup doc (#17868)
to help point searchers to the correct doc


[preview](https://coder.com/docs/@setup-ext-auth/admin/setup#continue-your-setup-with-external-authentication)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-20 15:10:52 -04:00
Thomas Kosiewski b551a062d7 fix: correct environment variable name for MCP app status slug (#17948)
Fixed environment variable name for app status slug in Claude MCP configuration from `CODER_MCP_CLAUDE_APP_STATUS_SLUG` to `CODER_MCP_APP_STATUS_SLUG` to maintain consistency with other MCP environment variables.

This also caused the User level Claude.md to not contain instructions to report its progress, so it did not receive status reports.
2025-05-20 19:35:19 +02:00
Julio 55313cffbc chore: add vsphere icon (#17936) 2025-05-20 17:19:38 +00:00
Edward Angert b51c902e48 docs: add early access badge to devcontainers admin (#17937)
[preview](https://coder.com/docs/@dev-container-tweaks/admin/templates/extending-templates/devcontainers)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-20 12:46:07 -04:00
Steven Masley a123900fe8 chore: remove coder/preview dependency from codersdk (#17939) 2025-05-20 10:45:12 -05:00
Steven Masley e76d58f2b6 chore: disable parameter validatation for dynamic params for all transitions (#17926)
Dynamic params skip parameter validation in coder/coder.
This is because conditional parameters cannot be validated 
with the static parameters in the database.
2025-05-20 10:09:53 -05:00
Thomas Kosiewski 93f17bc73e fix: remove unnecessary user lookup in agent API calls (#17934)
# Use workspace.OwnerUsername instead of fetching the owner

This PR optimizes the agent API by using the `workspace.OwnerUsername` field directly instead of making an additional database query to fetch the owner's username. The change removes the need to call `GetUserByID` in the manifest API and workspace agent RPC endpoints.

An issue arose when the agent token was scoped without access to user data (`api_key_scope = "no_user_data"`), causing the agent to fail to fetch the manifest due to an RBAC issue.

Change-Id: I3b6e7581134e2374b364ee059e3b18ece3d98b41
Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-05-20 17:07:50 +02:00
Danielle Maywood 1267c9c405 fix: ensure reason present for workspace autoupdated notification (#17935)
Fixes https://github.com/coder/coder/issues/17930

Update the `WorkspaceAutoUpdated` notification to only display the
reason if it is present.
2025-05-20 16:01:57 +01:00
Michael Suchacz 769c9ee337 feat: cancel stuck pending jobs (#17803)
Closes: #16488
2025-05-20 15:22:44 +02:00
Sas Swart 613117bde2 chore: add presets with prebuilds to our dogfood template (#17933)
This PR adds a preset with prebuilds for each region to our dogfood
template. Creating a workspace based on a preset should now save time
compared to creating a workspace from scratch
2025-05-20 14:45:26 +02:00
Ethan e5758a12c7 fix(site): center /cli-auth on firefox (#17929)
`-webkit-fill-available` is not available in Firefox: https://caniuse.com/mdn-css_properties_height_stretch
`-moz-available` doesn't work on `height`, so we have to use `100vh`.

Before:
<img width="1405" alt="image" src="https://github.com/user-attachments/assets/bd0f4390-50e9-47fa-8501-f3e3483d3c0d" />

After:
<img width="1329" alt="image" src="https://github.com/user-attachments/assets/f19f4b2a-3398-4d64-8e12-5cfcb84106a9" />


The existing CSS is retained in browsers that support `-webkit-fill-available`, i.e. chrome:
<img width="253" alt="image" src="https://github.com/user-attachments/assets/c1b356b4-c228-4580-a4c3-cddc2e0327b4" />
2025-05-20 14:25:13 +10:00
Jaayden Halko dc21016151 fix: get presets working correctly with dynamic params (#17923)
This adds a few fixes to get presets working correctly with dynamic
params

1. Changes to preset params need to be rendered and displayed correctly
2. Changes to preset params need to be sent to the websocket
3. Changes to preset params need to be marked as touched so they won't
be automatically changed later because of dynamic defaults. Dynamic
defaults means any default parameter value can be changed by the
websocket response unless edited by the user, set by autofill or set by
a preset.
2025-05-19 18:20:40 -04:00
Steven Masley 9c000468a1 chore: expose use_classic_parameter_flow on workspace response (#17925) 2025-05-19 21:59:15 +00:00
Bruno Quaresma cc53c4d1d5 fix: fix devcontainer port button (#17924) 2025-05-19 18:38:38 -03:00
Edward Angert 1314dbdc94 docs: add new dynamic parameters information to parameters doc (#17653)
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
Co-authored-by: Stephen Kirby <kirby@coder.com>
Co-authored-by: Stephen Kirby <58410745+stirby@users.noreply.github.com>
2025-05-19 21:23:53 +00:00
Susana Ferreira 0cac6a8c38 docs: add provisioner job state transition diagram (#17882)
# Description

Add a state transition diagram for provisioner jobs to the
documentation.

This PR introduces a new diagram illustrating the lifecycle and state
transitions of provisioner jobs. The diagram complements the existing
status table by providing a visual representation of how jobs move
between different states throughout their lifecycle.

# Changes

- Added a SVG diagram under the **Manage Provisioner Jobs**
documentation page, in the **Provisioner Job Status** section.
- Included a brief introductory text before the diagram.

Mermaid
[link](https://www.mermaidchart.com/play#pako:eNqFkD1PwzAQhv_KyRMdvPSDIUKVUFIGJtSyYQbXvjSW3DM4jiqE-O_YsRtFCMF49z6P75U_mXIaWcU454KUo9acKkEAocMzVkA4BC-toDFvrbuoTvoAz02CAO5vXgQ7hLgS7HUBnMOjO0LtUQbUcdxCHYEnJG3oFJFs1VdwNAvYRHA_EM3BZnrRnd8sRvTu6LeHQSns-3aw9mNUaZlapC1q1P_YFxM62HnvfHZX0X2Qxv4qSlJorQzGUXL3-D5gf21M66hmZF6a1kn_qeYT5eRf4FQ2s5vpxqwgbXJ4m75_RylYlGRVkjIup5F9fQNTV5aS)

---

Screenshot of `Provisioner job status` section in documentation page:

![Screenshot 2025-05-19 at 16 10
12](https://github.com/user-attachments/assets/9cd6a46e-24ae-450c-842c-9580d61a50f6)
2025-05-19 17:23:36 -04:00
Steven Masley 358b64154e chore: skip parameter resolution for dynamic params (#17922)
Pass through the user input as is. The previous code only passed through
parameters that existed in the db (static params). This would omit
conditional params.

Validation is enforced by the dynamic params websocket, so validation at
this point is not required.
2025-05-19 16:15:15 -05:00
Bruno Quaresma fe733afd14 chore: fix flake on useAgentLogs (#17919)
We need to wait for the result since the result is depending on effects.

Fix https://github.com/coder/internal/issues/644
2025-05-19 16:43:26 -03:00
Cian Johnston 433f0be53d fix: show provisioner name instead of key name in expanded ProvisionerKeyRow (#17921) 2025-05-19 14:35:22 -03:00
Bruno Quaresma ca5f114204 refactor: update cli auth page design (#17915)
Improve UX of CLI Auth page.

**Before:**

<img width="1512" alt="Screenshot 2025-05-19 at 09 22 36"
src="https://github.com/user-attachments/assets/ffcecebc-a289-4b06-993d-a170f2ba5e49"
/>

**After:**


https://github.com/user-attachments/assets/01dfcd70-d0a6-48bb-9186-77da24001498



Fixes https://github.com/coder/coder/issues/17905
2025-05-19 13:27:58 -03:00
Cian Johnston ac7961a5b0 feat: add Organization Provisioner Keys view (#17889)
Fixes https://github.com/coder/coder/issues/17698

**Demo:**


https://github.com/user-attachments/assets/ba92693f-29b7-43ee-8d69-3d77214f3230

---------

Co-authored-by: BrunoQuaresma <bruno_nonato_quaresma@hotmail.com>
2025-05-19 16:58:12 +01:00
Danielle Maywood 61f22a59ba feat(agent): add ParentId to agent manifest (#17888)
Closes https://github.com/coder/internal/issues/648

This change introduces a new `ParentId` field to the agent's manifest.
This will allow an agent to know if it is a child or not, as well as
knowing who the owner is.

This is part of the Dev Container Agents work
2025-05-19 16:09:56 +01:00
Susana Ferreira f044cc3550 feat: add provisioner daemon name to provisioner jobs responses (#17877)
# Description

This PR adds the `worker_name` field to the provisioner jobs endpoint.

To achieve this, the following SQL query was updated:
-
`GetProvisionerJobsByOrganizationAndStatusWithQueuePositionAndProvisioner`

As a result, the `codersdk.ProvisionerJob` type, which represents the
provisioner job API response, was modified to include the new field.

**Notes:** 
* As mentioned in
[comment](https://github.com/coder/coder/pull/17877#discussion_r2093218206),
the `GetProvisionerJobsByIDsWithQueuePosition` query was not changed due
to load concerns. This means that for template and template version
endpoints, `worker_id` will still be returned, but `worker_name` will
not.
* Similar to `worker_id`, the `worker_name` is only present once a job
is assigned to a provisioner daemon. For jobs in a pending state (not
yet assigned), neither `worker_id` nor `worker_name` will be returned.

---

# Affected Endpoints

- `/organizations/{organization}/provisionerjobs`
- `/organizations/{organization}/provisionerjobs/{job}`

---

# Testing

- Added new tests verifying that both `worker_id` and `worker_name` are
returned once a provisioner job reaches the **succeeded** state.
- Existing tests covering state transitions and other logic remain
unchanged, as they test different scenarios.

---

# Front-end Changes

Admin provisioner jobs dashboard:
<img width="1088" alt="Screenshot 2025-05-16 at 11 51 33"
src="https://github.com/user-attachments/assets/0e20e360-c615-4497-84b7-693777c5443e"
/>

Fixes: https://github.com/coder/coder/issues/16982
2025-05-19 16:05:39 +01:00
Danny Kopping 87dc2478a9 feat: fail CI when pubsub.Publish calls are found in db transactions (#17903)
Publishing inside a db transaction can lead to database connection
starvation/contention since it requires its own connection.

This ruleguard rule (one-shotted by Claude Sonnet 3.7 and finalized by
@Emyrk) will detect two of the following 3 instances:

```go
type Nested struct {
	ps pubsub.Pubsub
}

func TestFail(t *testing.T) {
	t.Parallel()

	db, ps := dbtestutil.NewDB(t)
	nested := &Nested{
		ps: ps,
	}

	// will catch this
	_ = db.InTx(func(_ database.Store) error {
		_, _ = fmt.Printf("")
		_ = ps.Publish("", []byte{})
		return nil
	}, nil)

	// will catch this
	_ = db.InTx(func(_ database.Store) error {
		_ = nested.ps.Publish("", []byte{})
		return nil
	}, nil)

	// will NOT catch this
	_ = db.InTx(func(_ database.Store) error {
		blah(ps)
		return nil
	}, nil)
}

func blah(ps pubsub.Pubsub) {
	ps.Publish("", []byte{})
}
```

The ruleguard doesn't recursively introspect function calls so only the
first two cases will be guarded against, but it's better than nothing.

<img width="1444" alt="image"
src="https://github.com/user-attachments/assets/8ffa0d88-16a0-41a9-9521-21211910dec9"
/>

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
2025-05-19 14:52:51 +00:00
Jaayden Halko 4412f194d4 fix: sync websocket params with form params (#17895)
The current issue is that when multiple parameters are added or removed
from a form because a user change in a conditional parameter value. The
websocket parameters response gets out of sync with the state of the
parameters in the form.

The form state needs to be maintained because this is what gets
submitted when the user attempts to create a workspace.

Fixes:

1. When autofill params are set from the url, mark these params as
touched in the form. This is necessary as only touched params are sent
in the request to the websocket. These params should technically count
as being touched because they were preset from the url params.

2. Create a hook to synchronize the parameters from the websocket
response with the current state of the parameters stored in the form.
2025-05-19 10:49:02 -04:00
Jaayden Halko 766277c20e fix: disable submit button on diagnostics error (#17900) 2025-05-19 10:43:56 -04:00
dependabot[bot] 4e0fc6e17c chore: bump github.com/hashicorp/terraform-json from 0.24.0 to 0.25.0 (#17914)
Bumps
[github.com/hashicorp/terraform-json](https://github.com/hashicorp/terraform-json)
from 0.24.0 to 0.25.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/hashicorp/terraform-json/releases">github.com/hashicorp/terraform-json's
releases</a>.</em></p>
<blockquote>
<h2>v0.25.0</h2>
<p>ENHANCEMENTS:</p>
<ul>
<li>Add identity fields to plan struct by <a
href="https://github.com/dbanck"><code>@​dbanck</code></a> in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/158">hashicorp/terraform-json#158</a></li>
<li>Update state and provider JSON with identity fields by <a
href="https://github.com/dbanck"><code>@​dbanck</code></a> in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/155">hashicorp/terraform-json#155</a></li>
</ul>
<p>INTERNAL:</p>
<ul>
<li>build(deps): Bump workflows to latest trusted versions by <a
href="https://github.com/hashicorp-tsccr"><code>@​hashicorp-tsccr</code></a>
in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/149">hashicorp/terraform-json#149</a></li>
<li>Bump github.com/zclconf/go-cty from 1.15.1 to 1.16.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/150">hashicorp/terraform-json#150</a></li>
<li>Bump github.com/zclconf/go-cty from 1.16.0 to 1.16.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/151">hashicorp/terraform-json#151</a></li>
<li>Bump github.com/zclconf/go-cty from 1.16.1 to 1.16.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/152">hashicorp/terraform-json#152</a></li>
<li>build(deps): Bump workflows to latest trusted versions by <a
href="https://github.com/hashicorp-tsccr"><code>@​hashicorp-tsccr</code></a>
in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/153">hashicorp/terraform-json#153</a></li>
<li>Bump github.com/google/go-cmp from 0.6.0 to 0.7.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/154">hashicorp/terraform-json#154</a></li>
<li>build(deps): Bump workflows to latest trusted versions by <a
href="https://github.com/hashicorp-tsccr"><code>@​hashicorp-tsccr</code></a>
in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/156">hashicorp/terraform-json#156</a></li>
<li>Update owner field in catalog-info.yaml by <a
href="https://github.com/imakewebthings"><code>@​imakewebthings</code></a>
in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/157">hashicorp/terraform-json#157</a></li>
<li>Update CODEOWNERS by <a
href="https://github.com/austinvalle"><code>@​austinvalle</code></a> in
<a
href="https://redirect.github.com/hashicorp/terraform-json/pull/159">hashicorp/terraform-json#159</a></li>
<li>github: Use Dependabot to keep Actions updated by <a
href="https://github.com/xiehan"><code>@​xiehan</code></a> in <a
href="https://redirect.github.com/hashicorp/terraform-json/pull/160">hashicorp/terraform-json#160</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/hashicorp/terraform-json/compare/v0.24.0...v0.25.0">https://github.com/hashicorp/terraform-json/compare/v0.24.0...v0.25.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/c2689b1b4ba628fb39555f9af6b521f0daa762ef"><code>c2689b1</code></a>
github: Use Dependabot to keep Actions updated (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/160">#160</a>)</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/6bc20aac0e8269158c60407c1829dc2ca0d1e11e"><code>6bc20aa</code></a>
Add identity fields to Plan struct (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/158">#158</a>)</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/b5939fa6c3c681207bef15a86cefb043e28ef2d9"><code>b5939fa</code></a>
Update CODEOWNERS (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/159">#159</a>)</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/c370ee72fd10bc381f46575470c889af0613d234"><code>c370ee7</code></a>
Update owner field in catalog-info.yaml (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/157">#157</a>)</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/0b330eb970cbf1718e4b188ea3f035268434f9c9"><code>0b330eb</code></a>
build(deps): Bump workflows to latest trusted versions (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/156">#156</a>)</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/f86d5e36f4ab36a15c5917e95863c230ef3acf7f"><code>f86d5e3</code></a>
Update state and provider JSON with identity fields (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/155">#155</a>)</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/4d6dac0a34e41b855e335e1f788cd43dc8ceb7cc"><code>4d6dac0</code></a>
Bump github.com/google/go-cmp from 0.6.0 to 0.7.0 (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/154">#154</a>)</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/323ee613daed7529cd2edf18d6e2738e0d886aa9"><code>323ee61</code></a>
Merge pull request <a
href="https://redirect.github.com/hashicorp/terraform-json/issues/153">#153</a>
from hashicorp/tsccr-auto-pinning/trusted/2025-02-03</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/2eb7d113bcfa08c4169b6c4252972965e194e345"><code>2eb7d11</code></a>
Result of tsccr-helper -log-level=info gha update -latest .github/</li>
<li><a
href="https://github.com/hashicorp/terraform-json/commit/0169f43a11d4a596463fc15e7f74896244e7b5d1"><code>0169f43</code></a>
Bump github.com/zclconf/go-cty from 1.16.1 to 1.16.2 (<a
href="https://redirect.github.com/hashicorp/terraform-json/issues/152">#152</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/hashicorp/terraform-json/compare/v0.24.0...v0.25.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/hashicorp/terraform-json&package-manager=go_modules&previous-version=0.24.0&new-version=0.25.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 13:47:12 +00:00
dependabot[bot] 9367ef1663 chore: bump cloud.google.com/go/compute/metadata from 0.6.0 to 0.7.0 (#17913)
Bumps
[cloud.google.com/go/compute/metadata](https://github.com/googleapis/google-cloud-go)
from 0.6.0 to 0.7.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-cloud-go/releases">cloud.google.com/go/compute/metadata's
releases</a>.</em></p>
<blockquote>
<h2>compute/metadata: v0.7.0</h2>
<h2><a
href="https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.6.0...compute/metadata/v0.7.0">0.7.0</a>
(2025-05-13)</h2>
<h3>Features</h3>
<ul>
<li><strong>compute/metadata:</strong> Allow canceling GCE detection (<a
href="https://redirect.github.com/googleapis/google-cloud-go/issues/11786">#11786</a>)
(<a
href="https://github.com/googleapis/google-cloud-go/commit/78100fe7e28cd30f1e10b47191ac3c9839663b64">78100fe</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md">cloud.google.com/go/compute/metadata's
changelog</a>.</em></p>
<blockquote>
<h2>v0.7.0</h2>
<ul>
<li>Release of a client library for Spanner. See
the
<a
href="https://cloudplatform.googleblog.com/2017/02/introducing-Cloud-Spanner-a-global-database-service-for-mission-critical-applications.html">blog
post</a>.
Note that although the Spanner service is beta, the Go client library is
alpha.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/2e6a95edb1071d750f6d7db777bf66cd2997af6c"><code>2e6a95e</code></a>
pubsub: fix flaky streaming retry test</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/581b8393c374fc0c5e3e91f07bc95935afb30df2"><code>581b839</code></a>
pubsub: check early if streaming iterator is already drained</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/cc13a9bec59f97f8ea60047fedd3005668851a70"><code>cc13a9b</code></a>
spanner: fix time.Time comparisons for upcoming Go1.9 monotonic
times</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/1ba9ec4b19f76eddfc8bf9fa5d08bab8f29a3581"><code>1ba9ec4</code></a>
spanner: remove most logging from tests</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/11737a05a487e168f31ed1722b7cf7bfca136caa"><code>11737a0</code></a>
spanner: skip some tests in short mode</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/7bcba8ac93ae2c1b8b040f2e53f363cf8e659173"><code>7bcba8a</code></a>
datastore: DRY up loading entity code</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/df9740f981cff9eb64dd60b92d8b9f38609f5ebd"><code>df9740f</code></a>
regenerate toolkit client</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/960c7688c840488daad1d2bb1fd3ee8c66b997a9"><code>960c768</code></a>
trace: export tracing scopes</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/8b0ab476b11e386cdd8fc619fa0a08c37214f0c2"><code>8b0ab47</code></a>
logadmin: retry on CreateMetric and UpdateMetric</li>
<li><a
href="https://github.com/googleapis/google-cloud-go/commit/20666962de1d3580350d6c3d4b63fc0e9720371f"><code>2066696</code></a>
trace: clarify how gRPC options work</li>
<li>Additional commits viewable in <a
href="https://github.com/googleapis/google-cloud-go/compare/v0.6.0...v0.7.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cloud.google.com/go/compute/metadata&package-manager=go_modules&previous-version=0.6.0&new-version=0.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 13:27:13 +00:00
dependabot[bot] 1a434582bb chore: bump github.com/mark3labs/mcp-go from 0.27.0 to 0.28.0 (#17909)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.27.0 to 0.28.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.28.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(tools): implicitly register capabilities by <a
href="https://github.com/david-hamilton-glean"><code>@​david-hamilton-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/292">mark3labs/mcp-go#292</a></li>
<li>fix: Gate notifications on capabilities by <a
href="https://github.com/david-hamilton-glean"><code>@​david-hamilton-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/290">mark3labs/mcp-go#290</a></li>
<li>feat(protocol): allow additional fields in meta by <a
href="https://github.com/anuraaga"><code>@​anuraaga</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/293">mark3labs/mcp-go#293</a></li>
<li>fix: type mismatch for request/response ID by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/291">mark3labs/mcp-go#291</a></li>
<li>feat(MCPServer): support <code>logging/setlevel</code> request by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/276">mark3labs/mcp-go#276</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/anuraaga"><code>@​anuraaga</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/293">mark3labs/mcp-go#293</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.27.1...v0.28.0">https://github.com/mark3labs/mcp-go/compare/v0.27.1...v0.28.0</a></p>
<h2>Release v0.27.1</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: add CONTRIBUTING.md by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/275">mark3labs/mcp-go#275</a></li>
<li>chore: create CODE_OF_CONDUCT.md by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/274">mark3labs/mcp-go#274</a></li>
<li>chore: add issue and pull request templates by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/281">mark3labs/mcp-go#281</a></li>
<li>ci: add golangci-lint by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/282">mark3labs/mcp-go#282</a></li>
<li>fix: proper deprecation messaging for WithHTTPContextFunc by <a
href="https://github.com/aotarola"><code>@​aotarola</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/278">mark3labs/mcp-go#278</a></li>
<li>chore: add a security policy by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/283">mark3labs/mcp-go#283</a></li>
<li>fix(docs): Update README link by <a
href="https://github.com/david-hamilton-glean"><code>@​david-hamilton-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/284">mark3labs/mcp-go#284</a></li>
<li>fix(session): Don't send tool changed notifications if session not
initialized yet by <a
href="https://github.com/david-hamilton-glean"><code>@​david-hamilton-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/289">mark3labs/mcp-go#289</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/aotarola"><code>@​aotarola</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/278">mark3labs/mcp-go#278</a></li>
<li><a
href="https://github.com/david-hamilton-glean"><code>@​david-hamilton-glean</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/284">mark3labs/mcp-go#284</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.27.0...v0.27.1">https://github.com/mark3labs/mcp-go/compare/v0.27.0...v0.27.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/077f546c180dcd6ba9ad3f8cdb30643ddd153297"><code>077f546</code></a>
feat(MCPServer): support <code>logging/setlevel</code> request (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/276">#276</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/09c23b5fec768432e3362bea05e69f57a3bc7c92"><code>09c23b5</code></a>
fix: type mismatch for request/response ID (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/291">#291</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/91ddba5f0b9cef6fd6b89cae1009b0ab55eeb1c0"><code>91ddba5</code></a>
feat(protocol): allow additional fields in meta (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/293">#293</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/eb835b903dbf9e9f6c594b2344a4e80d98cd0712"><code>eb835b9</code></a>
fix: Gate notifications on capabilities (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/290">#290</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/e7d2547fdc103cc64125097694e68a158beaeccb"><code>e7d2547</code></a>
feat(tools): implicitly register capabilities (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/292">#292</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/c1e70f336141a46227b221a558ae485a19f593eb"><code>c1e70f3</code></a>
fix(session): Don't send tool changed notifications if session not
initialize...</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/e767652eda0e93322fef218da0af4abeb4f62330"><code>e767652</code></a>
fix(docs): Update README link (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/284">#284</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/239cfa4aa3fb41b7e1e5fff788fdecd40451fe52"><code>239cfa4</code></a>
chore: add a security policy (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/283">#283</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/c46450cc8ef2ed9fc94836070104d2a1a3790107"><code>c46450c</code></a>
fix: proper deprecation messaging for WithHTTPContextFunc (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/278">#278</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/7bb1fd21abdac57cf7b5aeaf34025165f8552885"><code>7bb1fd2</code></a>
ci: add golangci-lint (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/282">#282</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.27.0...v0.28.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.27.0&new-version=0.28.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 12:29:59 +00:00
dependabot[bot] a07298a173 ci: bump github/codeql-action from 3.28.17 to 3.28.18 in the github-actions group (#17907)
Bumps the github-actions group with 1 update:
[github/codeql-action](https://github.com/github/codeql-action).

Updates `github/codeql-action` from 3.28.17 to 3.28.18
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.28.18</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.18 - 16 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2893">#2893</a></li>
<li>Skip validating SARIF produced by CodeQL for improved performance.
<a
href="https://redirect.github.com/github/codeql-action/pull/2894">#2894</a></li>
<li>The number of threads and amount of RAM used by CodeQL can now be
set via the <code>CODEQL_THREADS</code> and <code>CODEQL_RAM</code>
runner environment variables. If set, these environment variables
override the <code>threads</code> and <code>ram</code> inputs
respectively. <a
href="https://redirect.github.com/github/codeql-action/pull/2891">#2891</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.18/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.28.18 - 16 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2893">#2893</a></li>
<li>Skip validating SARIF produced by CodeQL for improved performance.
<a
href="https://redirect.github.com/github/codeql-action/pull/2894">#2894</a></li>
<li>The number of threads and amount of RAM used by CodeQL can now be
set via the <code>CODEQL_THREADS</code> and <code>CODEQL_RAM</code>
runner environment variables. If set, these environment variables
override the <code>threads</code> and <code>ram</code> inputs
respectively. <a
href="https://redirect.github.com/github/codeql-action/pull/2891">#2891</a></li>
</ul>
<h2>3.28.17 - 02 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2872">#2872</a></li>
</ul>
<h2>3.28.16 - 23 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.1. <a
href="https://redirect.github.com/github/codeql-action/pull/2863">#2863</a></li>
</ul>
<h2>3.28.15 - 07 Apr 2025</h2>
<ul>
<li>Fix bug where the action would fail if it tried to produce a debug
artifact with more than 65535 files. <a
href="https://redirect.github.com/github/codeql-action/pull/2842">#2842</a></li>
</ul>
<h2>3.28.14 - 07 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.0. <a
href="https://redirect.github.com/github/codeql-action/pull/2838">#2838</a></li>
</ul>
<h2>3.28.13 - 24 Mar 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.12 - 19 Mar 2025</h2>
<ul>
<li>Dependency caching should now cache more dependencies for Java
<code>build-mode: none</code> extractions. This should speed up
workflows and avoid inconsistent alerts in some cases.</li>
<li>Update default CodeQL bundle version to 2.20.7. <a
href="https://redirect.github.com/github/codeql-action/pull/2810">#2810</a></li>
</ul>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<h2>3.28.10 - 21 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.5. <a
href="https://redirect.github.com/github/codeql-action/pull/2772">#2772</a></li>
<li>Address an issue where the CodeQL Bundle would occasionally fail to
decompress on macOS. <a
href="https://redirect.github.com/github/codeql-action/pull/2768">#2768</a></li>
</ul>
<h2>3.28.9 - 07 Feb 2025</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/ff0a06e83cb2de871e5a09832bc6a81e7276941f"><code>ff0a06e</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2896">#2896</a>
from github/update-v3.28.18-b86edfc27</li>
<li><a
href="https://github.com/github/codeql-action/commit/a41e0844be4d25fcef7ce7fa536f3e30275a9a1c"><code>a41e084</code></a>
Update changelog for v3.28.18</li>
<li><a
href="https://github.com/github/codeql-action/commit/b86edfc27a1e0d3b55127a7496a1c770a02b2f84"><code>b86edfc</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2893">#2893</a>
from github/update-bundle/codeql-bundle-v2.21.3</li>
<li><a
href="https://github.com/github/codeql-action/commit/e93b90025f7c49dccc3ee640c4155b63eb9a6b39"><code>e93b900</code></a>
Merge branch 'main' into update-bundle/codeql-bundle-v2.21.3</li>
<li><a
href="https://github.com/github/codeql-action/commit/510dfa3460b15b34a807ab5609b4691aed5ebbee"><code>510dfa3</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2894">#2894</a>
from github/henrymercer/skip-validating-codeql-sarif</li>
<li><a
href="https://github.com/github/codeql-action/commit/492d7832457da825a964331d860789f3f19d105b"><code>492d783</code></a>
Merge branch 'main' into henrymercer/skip-validating-codeql-sarif</li>
<li><a
href="https://github.com/github/codeql-action/commit/83bdf3b7f92061d2f6d74e2a4555ecf719adad68"><code>83bdf3b</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2859">#2859</a>
from github/update-supported-enterprise-server-versions</li>
<li><a
href="https://github.com/github/codeql-action/commit/cffc916774454a5ead1c8fb7925abad20cda85e4"><code>cffc916</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2891">#2891</a>
from austinpray-mixpanel/patch-1</li>
<li><a
href="https://github.com/github/codeql-action/commit/4420887272f1c68c7c58ca2970bdfb5eb657cf08"><code>4420887</code></a>
Add deprecation warning for CodeQL 2.16.5 and earlier</li>
<li><a
href="https://github.com/github/codeql-action/commit/4e178c584157c51ff3d6fb87c764e7ed0715f82a"><code>4e178c5</code></a>
Update supported versions table in README</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/60168efe1c415ce0f5521ea06d5c2062adbeed1b...ff0a06e83cb2de871e5a09832bc6a81e7276941f">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.28.17&new-version=3.28.18)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 11:30:15 +00:00
Mathias Fredriksson 84478bd7d6 fix(dogfood/coder): add missing -f flag (#17906) 2025-05-19 11:25:54 +00:00
Mathias Fredriksson 3dbd4245be fix(dogfood/coder): stop docker containers and prune system on shutdown (#17904)
This change adds docker stop and docker system prune to the shutdown script so 
that it doesn't need to be done by the Docker host which will take a lot longer.

This change greatly speeds up workspace destruction:

```
2025-05-19 12:26:57.046+03:00 docker_container.workspace[0]: Destroying... [id=2685e2f456ba7b280c420219f19ef15384faa52c61ba7c087c7f109ffa6b1bda]
2025-05-19 12:27:07.046+03:00 docker_container.workspace[0]: Still destroying... [10s elapsed]
2025-05-19 12:27:16.734+03:00 docker_container.workspace[0]: Destruction complete after 20s
```

Follow-up for #17110
2025-05-19 13:23:22 +03:00
Mathias Fredriksson 98e2ec4417 feat: show devcontainer dirty status and allow recreate (#17880)
Updates #16424
2025-05-19 12:56:10 +03:00
Sas Swart c775ea8411 test: fix a race in TestReinit (#17902)
closes https://github.com/coder/internal/issues/632

`pubsubReinitSpy` used to signal that a subscription had happened before
it actually had.
This created a slight opportunity for the main goroutine to publish
before the actual subscription was listening. The published event was
then dropped, leading to a failed test.
2025-05-19 11:37:54 +02:00
Spike Curtis 1a41608035 fix: stop extending API key access if OIDC refresh is available (#17878)
fixes #17070

Cleans up our handling of APIKey expiration and OIDC to keep them separate concepts. For an OIDC-login APIKey, both the APIKey and OIDC link must be valid to login. If the OIDC link is expired and we have a refresh token, we will attempt to refresh.

OIDC refreshes do not have any effect on APIKey expiry.

https://github.com/coder/coder/issues/17070#issuecomment-2886183613 explains why this is the correct behavior.
2025-05-19 12:05:35 +04:00
Steven Masley ca5a78adbf chore: update preview to remove AsString panic on unknown fields (#17897) 2025-05-17 22:02:37 +00:00
Jaayden Halko ac8591ec8f fix: add null check (#17896) 2025-05-16 19:41:37 -04:00
Jaayden Halko d6cb9b49b7 feat: setup url autofill for dynamic parameters (#17739)
resolves coder/preview#80

Parameter autofill allows setting parameters from the url using the
format param.[param name]=["purple","green"]

Example:

http://localhost:8080/templates/coder/scratch/workspace?param.list=%5b%22purple%22%2c%22green%22%5d%0a

The goal is to maintain feature parity of for autofill with dynamic
parameters.

Note: user history autofill is no longer being used and is being
removed.
2025-05-16 18:05:33 -04:00
Bruno Quaresma 87a1ebc460 chore: replace MUI Button - 1 (#17865) 2025-05-16 12:31:32 -07:00
Jaayden Halko f8f4dc6875 feat: check for classic flow on the create workspace page (#17852)
the local storage key is only set when a user presses the opt-in or
opt-out buttons

Overall, this feels less annoying for users to have to opt-in/opt-out on
every visit to the create workspace page. Maybe less of a concern for
end users but more of a concern while dogfooding.

Pros:
- User gets the admin setting value for the template as long as they
didn't opt-in or opt-out
- User can choose to opt-in/out-out at will and their preference is
saved
2025-05-16 13:40:59 -04:00
Danny Kopping 8914f7a95b chore: improve prebuilds docs (#17850)
These items came up in an internal "bug bash" session yesterday.

@EdwardAngert note: I've reverted to the "transparent" phrasing; the
current docs confused a couple folks yesterday, and I feel that
"transparent" is clearly understood in this context.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Edward Angert <EdwardAngert@users.noreply.github.com>
2025-05-16 19:25:09 +02:00
M Atif Ali d564164eaf docs: update release calendar for 2.22 release (#17886) 2025-05-16 09:51:54 -07:00
Steven Masley f36fb67f57 chore: use static params when dynamic param metadata is missing (#17836)
Existing template versions do not have the metadata (modules + plan) in
the db. So revert to using static parameter information from the
original template import.

This data will still be served over the websocket.
2025-05-16 11:47:59 -05:00
M Atif Ali fb0e3d64db chore: remove update release calendar job (#17884) 2025-05-16 20:06:00 +05:00
brettkolodny 2cd3f999a6 feat: add one shot commands to the coder ssh command (#17779)
Closes #2154

> [!WARNING]  
> The tests in this PR were co-authored by AI
2025-05-16 10:09:46 -04:00
Hugo Dutka cb0f778baf chore: update setup-ramdisk-action (#17883)
Update setup-ramdisk-action to [a
version](https://github.com/coder/setup-ramdisk-action/commit/81c5c441bda00c6c3d6bcee2e5a33ed4aadbbcc1)
that instructs curl to fail on network errors and retry them.

It should mitigate flakes like the one seen here:
https://github.com/coder/coder/actions/runs/15068089742/job/42357451808#step:4:54
2025-05-16 15:21:25 +02:00
Spike Curtis 7f9ddd73c5 docs: remove link to closed Remote Desktop issue (#17881)
There is a link in our docs saying Remote Desktop is on the roadmap, but the issue is closed.
2025-05-16 16:08:59 +04:00
Danielle Maywood 83df55700b revert(agent): remove CODER_AGENT_IS_SUB_AGENT cli flag (#17875)
The RFC has changed, this information will be passed through the
manifest instead.
2025-05-16 11:04:21 +00:00
Danny Kopping cf98268031 chore: push proto changes to v1.6 (#17874)
`v1.5` is going out with release `v2.22`

I had to reorder `module_files` and `resource_replacements` because of
this.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-16 11:27:41 +02:00
Dean Sheather c7917ea9e5 chore: expose original length when serving slim binaries (#17735)
This will be used in the extensions and desktop apps to enable
compression AND progress reporting for the download by comparing the
original content length to the amount of bytes written to disk.

Closes #16340
2025-05-16 15:19:28 +10:00
Spike Curtis 90e93a2399 chore: fix agent tests on Windows 11 (#17631)
Fixes a couple agent tests so that they work correctly on Windows.

`HOME` is not a standard Windows environment variable, and we don't have any specific Code in Coder to set it on SSH, so I've removed the test case. Amazingly/bizarrely the Windows test runners set this variable, but this is not standard Windows behavior so we shouldn't be including it in our tests.

Also the command `true` is not valid on a default Windows install.

```
true: The term 'true' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
```

I'm not really sure how the CI runners are allowing this test to pass, but again, it's not standard so we shouldn't be doing it.
2025-05-16 07:50:29 +04:00
Bruno Quaresma 4ac41375a0 chore: replace MUI icons with Lucide icons - 15 (#17861)
AccountCircleOutlined -> CircleUserIcon
BugReportOutlined -> BugIcon
ChatOutlined -> MessageSquareIcon
ExitToAppOutlined -> LogOutIcon
LaunchOutlined -> SquareArrowOutUpRightIcon
MenuBook -> BookOpenTextIcon
OpenInNew -> EternalLinkIcon
EmailOutlined -> MailIcon
WebhookOutlined -> WebhookIcon
Business -> Building2Icon
Person -> UserIcon
2025-05-15 22:32:50 -03:00
Bruno Quaresma ea63d27e45 chore: migrate spinner components (#17866) 2025-05-15 22:29:58 -03:00
Steven Masley c2bc801f83 chore: add 'classic_parameter_flow' column setting to templates (#17828)
We are forcing users to try the dynamic parameter experience first.
Currently this setting only comes into effect if an experiment is
enabled.
2025-05-15 17:55:17 -05:00
Jaayden Halko 9063b67c4d chore: improve style of dynamic parameters diagnostics (#17863)
Before
<img width="756" alt="Screenshot 2025-05-15 at 19 10 24"
src="https://github.com/user-attachments/assets/405d904a-c06b-41d9-9641-0dbadeadde70"
/>


After
<img width="755" alt="Screenshot 2025-05-15 at 19 10 07"
src="https://github.com/user-attachments/assets/7c1e72b5-37d1-446b-af7e-aebfcf7553a3"
/>
2025-05-15 18:02:25 -04:00
Bruno Quaresma 3011eca0c5 chore: replace MUI icons with Lucide icons - 16 (#17862)
Close -> XIcon
WarningOutlined -> TriangleAlertIcon
FileCopyOutlined -> CopyIcon
KeyboardArrowRight -> ChevronRightIcon
Add -> PlusIcon
Send -> SendIcon
ChevronRight -> ChevronRightIcon
MoreHorizOutlined -> EllipsisIcon
2025-05-15 15:42:09 -03:00
Bruno Quaresma 952c254046 fix: fix duplicated agent logs (#17806)
Fix https://github.com/coder/coder/issues/16355
2025-05-15 15:21:33 -03:00
M Atif Ali 2c49fd9e96 feat: add copy button for workspace name in breadcrumb (#17822)
Co-authored-by: BrunoQuaresma <bruno_nonato_quaresma@hotmail.com>
2025-05-15 22:41:01 +05:00
Bruno Quaresma bbceebde97 chore: remove @mui/lab (#17857) 2025-05-15 13:21:53 -03:00
Tom Beckett bb6b96f11c feat: add elixir icon (#17848) 2025-05-15 20:34:32 +05:00
Bruno Quaresma 9beaca89fd chore: replace MUI LoadingButton - 3 (#17833)
- RequestOTPPage
- SetupPageView
- TemplatePermissionsPageView
- AccountForm
- ExternalAuthPageView
2025-05-15 12:08:48 -03:00
Bruno Quaresma 257500c12f chore: replace MUI icons with Lucide icons - 14 (#17832)
HourglassEmpty -> HourglassIcon
Star -> StarIcon
CloudQueue -> CloudIcon
InstallDesktop -> MonitorDownIcon
WarningRounded -> TriangleAlertIcon
ArrowBackOutlined -> ChevronLeftIcon
MonetizationOnOutlined -> CircleDollarSign
2025-05-15 12:08:35 -03:00
Bruno Quaresma 6ff6e95417 chore: replace MUI icons with Lucide icons - 13 (#17831)
OpenInNew -> ExternalLinkIcon
InfoOutlined -> InfoIcon
CloudDownload -> CloudDownloadIcon
CloudUpload -> CloudUploadIcon
Compare -> GitCompareArrowsIcon
SettingsEthernet -> GaugeIcon
WebAsset -> AppWindowIcon
2025-05-15 11:43:35 -03:00
Bruno Quaresma ba6690f2ee fix: show no provisioners warning (#17835)
<img width="1510" alt="Screenshot 2025-05-14 at 14 53 02"
src="https://github.com/user-attachments/assets/f9c0fbb9-ea39-4fbc-a550-00d9f609a01e"
/>

Fix https://github.com/coder/coder/issues/17421
2025-05-15 11:37:20 -03:00
Thomas Kosiewski 1bacd82e80 feat: add API key scope to restrict access to user data (#17692) 2025-05-15 15:32:52 +01:00
Bruno Quaresma ee2aeb44d7 fix: avoid pulling containers when it is not enabled (#17855)
We've been continuously pulling the containers endpoint even when the
agent does not support containers. To optimize the requests, we can
check if it is throwing an error and stop if it is a 403 status code.
2025-05-15 11:13:09 -03:00
Edward Angert c42a3156cc docs: add dev containers to manifest.json (#17854)
[preview](http://coder.com/docs/@dev-container-manifest/admin/templates/extending-templates/devcontainers)
2025-05-15 13:18:21 +00:00
Mathias Fredriksson 3de0003e4b feat(agent): send devcontainer CLI logs during recreate (#17845)
We need a way to surface what's happening to the user, since autostart
logs here, it's natural we do so during re-create as well.

Updates #16424
2025-05-15 16:06:56 +03:00
Hugo Dutka 6e1ba75b06 chore: retry failed race tests in CI (#17846)
This PR enables retrying failed tests in the race suites unless a data
race was detected. The goal is to reduce how often flakes disrupt
developers' workflows.

I bumped gotestsum to a revision from the `main` branch because it
includes the `--rerun-fails-abort-on-data-race` flag which [I recently
contributed](https://github.com/gotestyourself/gotestsum/pull/497).

Incidentally, you can see it [in action in a CI job on this very
PR](https://github.com/coder/coder/actions/runs/15040840724/job/42271999592?pr=17846#step:8:647).
2025-05-15 14:11:36 +02:00
Yevhenii Shcherbina 2aa8cbebd7 fix: exclude deleted templates from metrics collection (#17839)
Also add some clarification about the lack of database constraints for
soft template deletion.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Danny Kopping <dannykopping@gmail.com>
2025-05-15 13:33:58 +02:00
Danny Kopping f2edcf3f59 fix: add missing clause for tracking replacements (#17849)
We should only be tracking resource replacements during a prebuild
claim.

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-15 13:02:30 +02:00
Mathias Fredriksson 522c178271 fix(agent/agentcontainers): always use /bin/sh for devcontainer autostart (#17847)
This fixes startup issues when the user shell is set to Fish.

Refs: #17845
2025-05-15 12:49:52 +03:00
Mathias Fredriksson eb6412a69b refactor(agent/agentcontainers): update routes and locking in container api (#17768)
This refactor updates the devcontainer routes and in-api locking for
better clarity.

Updates #16424
2025-05-15 11:29:26 +03:00
Bruno Quaresma b6d72c8dee chore: replace MUI LoadingButton - 4 (#17834)
- ScheduleForm
- SecurityForm
- HistorySidebar
- WorkspacesPageView
2025-05-14 22:18:10 -03:00
Bruno Quaresma 35a04c7fb2 refactor: use the new Table component for the Templates table (#17838)
<img width="1624" alt="Screenshot 2025-05-14 at 15 11 56"
src="https://github.com/user-attachments/assets/01fd5fe2-35d4-4fae-a668-68af2b9f9bd6"
/>
2025-05-14 17:11:32 -03:00
brettkolodny 73251cf5b2 chore: add documentation to the coder ssh command regarding feature parity with ssh (#17827)
Closes
[coder/internal#628](https://github.com/coder/internal/issues/628)

---------

Co-authored-by: M Atif Ali <atif@coder.com>
2025-05-14 15:42:44 -04:00
brettkolodny 9093dbc516 feat: hide hidden and non-healthy apps in the workspaces table (#17830)
Closes
[coder/internal#633](https://github.com/coder/internal/issues/633)
2025-05-14 13:51:45 -04:00
Steven Masley 789c4beba7 chore: add dynamic parameter error if missing metadata from provisioner (#17809) 2025-05-14 12:21:36 -05:00
ケイラ f3bcac2e90 refactor: improve overlayFS errors (#17808) 2025-05-14 10:26:47 -06:00
dependabot[bot] 4d00b76ef4 chore: bump github.com/justinas/nosurf from 1.1.1 to 1.2.0 (#17829)
Bumps [github.com/justinas/nosurf](https://github.com/justinas/nosurf)
from 1.1.1 to 1.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/justinas/nosurf/releases">github.com/justinas/nosurf's
releases</a>.</em></p>
<blockquote>
<h2>v1.2.0</h2>
<p>This is a <em>security</em> release for nosurf. It mainly addresses
<a
href="https://github.com/justinas/nosurf-cve-2025-46721">CVE-2025-46721</a>.</p>
<p>This release technically includes breaking changes, as nosurf starts
applying same-origin checks that were not previously enforced. In most
cases, users will not need to make any changes to their code. However,
it is recommended to read <a
href="https://github.com/justinas/nosurf/blob/master/docs/origin-checks.md">the
documentation on nosurf's trusted origin checks</a> before
upgrading.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/justinas/nosurf/commit/ec9bb776d8e5ba9e906b6eb70428f4e7b009feee"><code>ec9bb77</code></a>
Rework origin checks (<a
href="https://redirect.github.com/justinas/nosurf/issues/74">#74</a>)</li>
<li><a
href="https://github.com/justinas/nosurf/commit/e5c9c1fe2d4f69668ff78f872abf3b396a08673a"><code>e5c9c1f</code></a>
Add GitHub Actions CI, fix lints and tests</li>
<li>See full diff in <a
href="https://github.com/justinas/nosurf/compare/v1.1.1...v1.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/justinas/nosurf&package-manager=go_modules&previous-version=1.1.1&new-version=1.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-14 15:08:52 +00:00
Edward Angert 74934e174e docs: add file sync to coder desktop docs (#17463)
closes #16869 

section could use more about:

- [x] sync direction options?
- [x] how to resolve conflicts
- [x] EA --> Beta


[preview](https://coder.com/docs/@16869-desktop-file-sync/user-guides/desktop)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-14 10:05:33 -04:00
Bruno Quaresma df56a13947 chore: replace MUI icons with Lucide icons - 12 (#17815)
AddOutlined -> PlusIcon
RemoveOutlined -> TrashIcon
ScheduleOutlined -> ClockIcon
2025-05-14 09:54:19 -03:00
Danny Kopping 6e967780c9 feat: track resource replacements when claiming a prebuilt workspace (#17571)
Closes https://github.com/coder/internal/issues/369

We can't know whether a replacement (i.e. drift of terraform state
leading to a resource needing to be deleted/recreated) will take place
apriori; we can only detect it at `plan` time, because the provider
decides whether a resource must be replaced and it cannot be inferred
through static analysis of the template.

**This is likely to be the most common gotcha with using prebuilds,
since it requires a slight template modification to use prebuilds
effectively**, so let's head this off before it's an issue for
customers.

Drift details will now be logged in the workspace build logs:


![image](https://github.com/user-attachments/assets/da1988b6-2cbe-4a79-a3c5-ea29891f3d6f)

Plus a notification will be sent to template admins when this situation
arises:


![image](https://github.com/user-attachments/assets/39d555b1-a262-4a3e-b529-03b9f23bf66a)

A new metric - `coderd_prebuilt_workspaces_resource_replacements_total`
- will also increment each time a workspace encounters replacements.

We only track _that_ a resource replacement occurred, not how many. Just
one is enough to ruin a prebuild, but we can't know apriori which
replacement would cause this.
For example, say we have 2 replacements: a `docker_container` and a
`null_resource`; we don't know which one might
cause an issue (or indeed if either would), so we just track the
replacement.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-14 14:52:22 +02:00
Bruno Quaresma e75d1c1ce5 chore: replace MUI LoadingButton with Button + Spinner - 2 (#17817) 2025-05-14 09:37:01 -03:00
Bruno Quaresma c7bc4047ba chore: replace MUI LoadingButton with Button + Spinner - 1 (#17816) 2025-05-14 09:35:21 -03:00
Sas Swart 425ee6fa55 feat: reinitialize agents when a prebuilt workspace is claimed (#17475)
This pull request allows coder workspace agents to be reinitialized when
a prebuilt workspace is claimed by a user. This facilitates the transfer
of ownership between the anonymous prebuilds system user and the new
owner of the workspace.

Only a single agent per prebuilt workspace is supported for now, but
plumbing has already been done to facilitate the seamless transition to
multi-agent support.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Danny Kopping <dannykopping@gmail.com>
2025-05-14 14:15:36 +02:00
Bruno Quaresma fcbdd1a28e refactor: replace badge by status indicator (#17811)
**Why?**
In the workspaces page, it is using the status indicator, and not the
badge anymore, so to keep the UI consistent, I'm replacing the badge by
the indicator in the workspace page too.

**Before:**
<img width="672" alt="Screenshot 2025-05-13 at 19 14 17"
src="https://github.com/user-attachments/assets/0e8ea4bd-68d1-4d27-b81b-f79f15cabb2c"
/>

**After:**
<img width="672" alt="Screenshot 2025-05-13 at 19 14 21"
src="https://github.com/user-attachments/assets/45719262-011e-4fc8-9ebe-fe9e33d9d572"
/>
2025-05-14 09:11:25 -03:00
Bruno Quaresma 80e1be0db1 fix: replace wrong emoji reference (#17810)
Before:
<img width="713" alt="Screenshot 2025-05-13 at 19 01 15"
src="https://github.com/user-attachments/assets/9e4438a4-28db-4d94-a9ce-cecfb73ce8ab"
/>

After:
<img width="713" alt="Screenshot 2025-05-13 at 19 02 22"
src="https://github.com/user-attachments/assets/627ddbb2-45d1-48a1-bd34-a998e11966a2"
/>
2025-05-14 09:03:01 -03:00
Bruno Quaresma f87dbe757e chore: replace MUI icons with Lucide icons - 11 (#17814)
PersonOutlined -> UserIcon
Schedule -> ClockIcon
SettingsSuggest -> SettingsIcon
SettingsOutlined -> SettingsIcon
CodeOutlined -> CodeIcon
TimerOutlined -> TimerIcon
2025-05-14 08:48:08 -03:00
Bruno Quaresma c71839294b fix: don't open a window for external apps (#17813)
This prevents empty windows like the following to happen:

![image](https://github.com/user-attachments/assets/0a444938-316e-4d48-bdfc-770d1b4b2bf0)
2025-05-14 08:41:33 -03:00
Bruno Quaresma 67e40244a4 feat: add extra workspace actions in the workspaces table (#17775)
**Demo:**
<img width="1624" alt="Screenshot 2025-05-12 at 16 53 36"
src="https://github.com/user-attachments/assets/7f125b31-5ce8-4c1f-8e26-c3136346cae3"
/>
2025-05-13 18:53:43 -03:00
ケイラ 60762d4c13 feat: load terraform modules when using dynamic parameters (#17714) 2025-05-13 16:07:29 -05:00
Edward Angert f9817af11f docs: add section on how to retrieve user list (#17798)
previews
- [admin/users](https://coder.com/docs/@export-coder-users/admin/users)
-
[reference/cli/users](https://coder.com/docs/@export-coder-users/reference/cli/users)

followup to slack thread:

> Tim
> what's the best way for customers to export a list of Coder users?
>
> @ericpaulsen
> the `/api/v2/users` API route returns all users in the deployment
(along with other information - email, status, username, etc.). from
<https://coder.com/docs/reference/api/users#get-users>


- adds an easy-to-find section to the admin/users doc
- updates the cli commands with short descriptions

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
2025-05-13 20:48:16 +00:00
M Atif Ali 170f41ac55 chore: fix release calendar and script (#17745)
Updates the script for the release calendar to use the actual release
dates.

This is done to work around the anomaly of the delayed May release.
2025-05-14 00:04:37 +05:00
Dean Sheather ef745c0c5d chore: optimize workspace_latest_builds view query (#17789)
Avoids two sequential scans of massive tables (`workspace_builds`,
`provisioner_jobs`) and uses index scans instead. This new view largely
replicates our already optimized query `GetWorkspaces` to fetch the
latest build.

The original query and the new query were compared against the dogfood
database to ensure they return the exact same data in the exact same
order (minus the new `workspaces.deleted = false` filter to improve
performance even more). The performance is massively improved even
without the `workspaces.deleted = false` filter, but it was added to
improve it even more.

Note: these query times are probably inflated due to high database load
on our dogfood environment that this intends to partially resolve.

Before: 2,139ms
([explain](https://explain.dalibo.com/plan/997e4fch241b46e6))

After: 33ms
([explain](https://explain.dalibo.com/plan/c888dc223870f181))

Co-authored-by: Cian Johnston <cian@coder.com>

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
Co-authored-by: Danny Kopping <dannykopping@gmail.com>
2025-05-13 20:51:01 +02:00
Danny Kopping b2a1de9e2a feat: fetch prebuilds metrics state in background (#17792)
`Collect()` is called whenever the `/metrics` endpoint is hit to
retrieve metrics.

The queries used in prebuilds metrics collection are quite heavy, and we
want to avoid having them running concurrently / too often to keep db
load down.

Here I'm moving towards a background retrieval of the state required to
set the metrics, which gets invalidated every interval.

Also introduces `coderd_prebuilt_workspaces_metrics_last_updated` which
operators can use to determine when these metrics go stale.

See https://github.com/coder/coder/pull/17789 as well.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-13 20:27:41 +02:00
Bruno Quaresma 709445e6fb chore: replace MUI icons with Lucide icons - 9 (#17796)
OpenInNew -> ExternalLinkIcon
KeyboardArrowLeft -> ChevronLeftIcon
KeyboardArrowRight -> ChevronRightIcon
Settings -> SettingsIcon
2025-05-13 13:53:06 -04:00
Steven Masley 64807e1d61 chore: apply the 4mb max limit on drpc protocol message size (#17771)
Respect the 4mb max limit on proto messages
2025-05-13 11:24:51 -05:00
Cian Johnston a1c03b6c5f feat: add experimental Chat UI (#17650)
Builds on https://github.com/coder/coder/pull/17570

Frontend portion of https://github.com/coder/coder/tree/chat originally
authored by @kylecarbs

Additional changes:
- Addresses linter complaints
- Brings `ChatToolInvocation` argument definitions in line with those
defined in `codersdk/toolsdk`
- Ensures chat-related features are not shown unless
`ExperimentAgenticChat` is enabled.

Co-authored-by: Kyle Carberry <kyle@carberry.com>
2025-05-13 17:24:10 +01:00
Charlie Voiselle 8f64d49b22 chore: update alpine 3.21.2 => 3.21.3 (#17773)
Resolves 3 CVEs in base container (1 High, 2 Medium)

| CVE ID         | CVSS Score | Package / Version               |
| -------------- | ---------- | ------------------------------  |
| CVE-2025-26519 | 8.1 High   | apk / alpine/musl / 1.2.5-r8    |
| CVE-2024-12797 | 6.3 Medium | apk / alpine/openssl / 3.3.2-r4 |
| CVE-2024-13176 | 4.1 Medium | apk / alpine/openssl / 3.3.2-r4 |
2025-05-13 11:49:56 -04:00
Bruno Quaresma 86da21c491 chore: replace MUI icons with Lucide icons - 10 (#17797)
CloseOutlined -> XIcon
SearchOutlined -> SearchIcon
Refresh -> RotateCwIcon
Build -> WrenchIcon
2025-05-13 12:31:36 -03:00
Bruno Quaresma eb9a651acd chore: replace MUI icons with Lucide icons - 8 (#17778)
1. Replaced CheckOutlined with CheckIcon in:
  - TemplateVersionStatusBadge.tsx
  - TemplateEmbedPage.tsx
  - IntervalMenu.tsx
  - WeekPicker.tsx
  - SelectMenu.tsx
2. Replaced EditCalendarOutlined with CalendarCogIcon in:
  - UserSettingsPage/Sidebar.tsx
  - Sidebar.stories.tsx
3. Replaced LockOutlined with LockIcon in:
  - UserSettingsPage/Sidebar.tsx
  - TemplateSettingsPage/Sidebar.tsx
  - Sidebar.stories.tsx
4. Replaced Person with UserIcon in:
  - UserSettingsPage/Sidebar.tsx
  - Sidebar.stories.tsx
5. Replaced VpnKeyOutlined with KeyIcon in:
  - UserSettingsPage/Sidebar.tsx
  - Sidebar.stories.tsx
6. Replaced FingerprintOutlined with FingerprintIcon in:
  - UserSettingsPage/Sidebar.tsx
  - Sidebar.stories.tsx
2025-05-13 10:09:45 -03:00
Bruno Quaresma 02425ee864 chore: replace MUI icons with Lucide icons - 7 (#17776)
VisibilityOffOutlined -> EyeOffIcon
VisibilityOutlined -> EyeIcon
2025-05-13 10:08:41 -03:00
Danielle Maywood b0788f410f chore: rename "Test Notification" to "Troubleshooting Notification" (#17790)
Rename the "Test Notification" to "Troubleshooting Notification"
2025-05-13 13:52:55 +01:00
Susana Ferreira 599bb35a04 fix(coderd): list templates returns non-deprecated templates by default (#17747)
## Description

Modifies the behaviour of the "list templates" API endpoints to return
non-deprecated templates by default. Users can still query for
deprecated templates by specifying the `deprecated=true` query
parameter.

**Note:** The deprecation feature is an enterprise-level feature

## Affected Endpoints
* /api/v2/organizations/{organization}/templates
* /api/v2/templates

Fixes #17565
2025-05-13 12:44:46 +01:00
Danielle Maywood 7f056da088 feat: add hidden CODER_AGENT_IS_SUB_AGENT flag to coder agent (#17783)
Closes https://github.com/coder/internal/issues/620

Adds a new, hidden, flag `CODER_AGENT_IS_SUB_AGENT` to the `coder agent`
command.
2025-05-13 10:57:50 +01:00
Danielle Maywood 0b5f27f566 feat: add parent_id column to workspace_agents table (#17758)
Adds a new nullable column `parent_id` to `workspace_agents` table. This
lays the groundwork for having child agents.
2025-05-13 00:01:31 +01:00
Steven Masley 398b999d8f chore: pass previous values into terraform apply (#17696)
Pass previous workspace build parameter values into the terraform
`plan/apply`. Enforces monotonicity in terraform as well as `coderd`.
2025-05-12 15:32:00 -05:00
ケイラ d0ab91c16f fix: reduce size of terraform modules archive (#17749) 2025-05-12 13:50:07 -06:00
ケイラ 10b44a5d1d fix: use monochrome zed icon (#17774) 2025-05-12 13:18:18 -06:00
Callum Styan 578b9ff5fe fix: enrich the notLoggedInMessage error message with the full path to the coder (#17715)
---------

Signed-off-by: Callum Styan <callumstyan@gmail.com>
2025-05-12 11:45:24 -07:00
Bruno Quaresma 15bd7a3add chore: replace MUI icons with Lucide icons - 5 (#17750)
Replacements:

MUI | Lucide
OpenInNewOutlined | ExternalLinkIcon
HelpOutline | CircleHelpIcon
ErrorOutline | CircleAlertIcon
2025-05-12 13:36:51 -03:00
Cian Johnston e0dd50d7fb chore(cli): fix test flake in TestExpMcpServer (#17772)
Test was failing inside a Coder workspace.
2025-05-12 17:15:24 +01:00
Hugo Dutka ea2cae0e20 chore: tune postgres CI tests (#17756)
Changes:
- use a bigger runner for test-go-pg on Linux
- use a depot runner to run postgres tests on Windows
- use the same Windows ramdisk action for postgres tests as the one
currently used for in-memory tests
- put GOTMPDIR on a ramdisk on Windows
- tune the number of tests running in parallel on macOS and Windows
- use a ramdisk for postgres on macOS
- turn off Spotlight indexing on macOS
- rerun failing tests to stop flakes from disrupting developers

Results:
- test-go-pg on Linux completing in 50% of the time it takes to run on
main ([run on
main](https://github.com/coder/coder/actions/runs/14937632073/job/41968714750),
[run on this
PR](https://github.com/coder/coder/actions/runs/14956584795/job/42013097674?pr=17756))
- macOS tests completing in 70% of the time ([run on
main](https://github.com/coder/coder/actions/runs/14921155015/job/41916639889),
[run on this
PR](https://github.com/coder/coder/actions/runs/14956590940/job/42013102975))
- Windows tests completing in 50% of the time ([run on
main](https://github.com/coder/coder/actions/runs/14921155015/job/41916640058),
[run on this
PR](https://github.com/coder/coder/actions/runs/14956590940/job/42013103116))

This PR helps unblock https://github.com/coder/coder/issues/15109.
2025-05-12 17:38:25 +02:00
Steven Masley 37832413ba chore: resolve internal drpc package conflict (#17770)
Our internal drpc package name conflicts with the external one in usage. 
`drpc.*` == external
`drpcsdk.*` == internal
2025-05-12 10:31:38 -05:00
Danny Kopping af2941bb92 feat: add is_prebuild_claim to distinguish post-claim provisioning (#17757)
Used in combination with
https://github.com/coder/terraform-provider-coder/pull/396

This is required by both https://github.com/coder/coder/pull/17475 and
https://github.com/coder/coder/pull/17571

Operators may need to conditionalize their templates to perform certain
operations once a prebuilt workspace has been claimed. This value will
**only** be set once a claim takes place and a subsequent `terraform
apply` occurs. Any `terraform apply` runs thereafter will be
indistinguishable from a normal run on a workspace.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-12 14:19:03 +00:00
dependabot[bot] 799a0ba573 chore: bump github.com/valyala/fasthttp from 1.61.0 to 1.62.0 (#17766)
Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp)
from 1.61.0 to 1.62.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/valyala/fasthttp/releases">github.com/valyala/fasthttp's
releases</a>.</em></p>
<blockquote>
<h2>v1.62.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add support for streaming identity-encoded or unknown length
response bodies by <a
href="https://github.com/osxtest"><code>@​osxtest</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/2000">valyala/fasthttp#2000</a></li>
<li>feat: move user values to Request structure by <a
href="https://github.com/mdenushev"><code>@​mdenushev</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1999">valyala/fasthttp#1999</a></li>
<li>chore(deps): bump golangci/golangci-lint-action from 7 to 8 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/2001">valyala/fasthttp#2001</a></li>
<li>chore(deps): bump golang.org/x/crypto from 0.37.0 to 0.38.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/2002">valyala/fasthttp#2002</a></li>
<li>chore(deps): bump golang.org/x/net from 0.39.0 to 0.40.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/2003">valyala/fasthttp#2003</a></li>
<li>modify <code>acceptConn</code> for <code>RIO</code> by <a
href="https://github.com/wamshawn"><code>@​wamshawn</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/2005">valyala/fasthttp#2005</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/osxtest"><code>@​osxtest</code></a> made
their first contribution in <a
href="https://redirect.github.com/valyala/fasthttp/pull/2000">valyala/fasthttp#2000</a></li>
<li><a href="https://github.com/wamshawn"><code>@​wamshawn</code></a>
made their first contribution in <a
href="https://redirect.github.com/valyala/fasthttp/pull/2005">valyala/fasthttp#2005</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/valyala/fasthttp/compare/v1.61.0...v1.62.0">https://github.com/valyala/fasthttp/compare/v1.61.0...v1.62.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/valyala/fasthttp/commit/9e457ebd982fe77cce75b59667ff20d4c3af30b2"><code>9e457eb</code></a>
mod acceptConn (<a
href="https://redirect.github.com/valyala/fasthttp/issues/2005">#2005</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/69a68df4eb257570ffed33b85a8e6d523b07ed70"><code>69a68df</code></a>
chore(deps): bump golang.org/x/net from 0.39.0 to 0.40.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/2003">#2003</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/83fbe80f9379db8388b4ee24a2eaab4674998b3f"><code>83fbe80</code></a>
chore(deps): bump golang.org/x/crypto from 0.37.0 to 0.38.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/2002">#2002</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/51817a4eb67dabb67e0870efccb20caafe0a936d"><code>51817a4</code></a>
chore(deps): bump golangci/golangci-lint-action from 7 to 8 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/2001">#2001</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/41a1449627b8ba0cbf30030ea41fc1ae4ca514f2"><code>41a1449</code></a>
feat: move user values to Request structure (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1999">#1999</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/1345f42ede3f31b6fe6b42342256f338261bd9d5"><code>1345f42</code></a>
Add support for streaming identity-encoded or unknown length response
bodies ...</li>
<li>See full diff in <a
href="https://github.com/valyala/fasthttp/compare/v1.61.0...v1.62.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/valyala/fasthttp&package-manager=go_modules&previous-version=1.61.0&new-version=1.62.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 12:24:00 +00:00
dependabot[bot] 345a239838 chore: bump github.com/open-policy-agent/opa from 1.3.0 to 1.4.2 (#17674)
Bumps
[github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa)
from 1.3.0 to 1.4.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/open-policy-agent/opa/releases">github.com/open-policy-agent/opa's
releases</a>.</em></p>
<blockquote>
<h2>v1.4.2</h2>
<p>This is a bug fix release addressing the missing
<code>capabilities/v1.4.1.json</code> in the v1.4.1 release.</p>
<h2>v1.4.1</h2>
<p>⚠️ Please skip this release and go straight to v1.4.2 ⚠️
This release is broken due to a mistake during the release process and
the artifacts are missing a crucial capabilities file.
Sorry for any inconvenience.</p>
<hr />
<p>This is a security fix release for the fixes published in Go <a
href="https://groups.google.com/g/golang-announce/c/4t3lzH3I0eI">1.24.1</a>
and <a
href="https://groups.google.com/g/golang-announce/c/Y2uBTVKjBQk">1.24.2</a></p>
<ul>
<li>build: bump go to 1.24.2 (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7544">#7544</a>)
(authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a>)
Addressing <code>CVE-2025-22870</code> and <code>CVE-2025-22871</code>
vulnerabilities in the Go runtime.</li>
</ul>
<h2>v1.4.0</h2>
<p>This release contains a security fix addressing CVE-2025-46569.
It also includes a mix of new features, bugfixes, and dependency
updates.</p>
<h4>Security Fix: CVE-2025-46569 - OPA server Data API HTTP path
injection of Rego (<a
href="https://github.com/open-policy-agent/opa/security/advisories/GHSA-6m8w-jc87-6cr7">GHSA-6m8w-jc87-6cr7</a>)</h4>
<p>A vulnerability in the OPA server's <a
href="https://www.openpolicyagent.org/docs/latest/rest-api/#data-api">Data
API</a> allows an attacker to craft the HTTP path in a way that injects
Rego code into the query that is evaluated.<br />
The evaluation result cannot be made to return any other data than what
is generated by the requested path, but this path can be misdirected,
and the injected Rego code can be crafted to make the query succeed or
fail; opening up for oracle attacks or, given the right circumstances,
erroneous policy decision results.
Furthermore, the injected code can be crafted to be computationally
expensive, resulting in a Denial Of Service (DoS) attack.</p>
<p><strong>Users are only impacted if all of the following
apply:</strong></p>
<ul>
<li>OPA is deployed as a standalone server (rather than being used as a
Go library)</li>
<li>The OPA server is exposed outside of the local host in an untrusted
environment.</li>
<li>The configured <a
href="https://www.openpolicyagent.org/docs/latest/security/#authentication-and-authorization">authorization
policy</a> does not do exact matching of the input.path attribute when
deciding if the request should be allowed.</li>
</ul>
<p><strong>or, if all of the following apply:</strong></p>
<ul>
<li>OPA is deployed as a standalone server.</li>
<li>The service connecting to OPA allows 3rd parties to insert
unsanitised text into the path of the HTTP request to OPA’s Data
API.</li>
</ul>
<p>Note: With <strong>no</strong> <a
href="https://www.openpolicyagent.org/docs/latest/security/#authentication-and-authorization">Authorization
Policy</a> configured for restricting API access (the default
configuration), the RESTful <a
href="https://www.openpolicyagent.org/docs/latest/rest-api/#data-api">Data
API</a> provides access for managing Rego policies; and the RESTful <a
href="https://www.openpolicyagent.org/docs/latest/rest-api/#query-api">Query
API</a> facilitates advanced queries.
Full access to these APIs provides both simpler, and broader access than
what the security issue describes here can facilitate.
As such, OPA servers exposed to a network are <strong>not</strong>
considered affected by the attack described here if they are knowingly
not restricting access through an Authorization Policy.</p>
<p>This issue affects all versions of OPA prior to 1.4.0.</p>
<p>See the <a
href="https://github.com/open-policy-agent/opa/security/advisories/GHSA-6m8w-jc87-6cr7">Security
Advisory</a> for more details.</p>
<p>Reported by <a
href="https://github.com/GamrayW"><code>@​GamrayW</code></a>, <a
href="https://github.com/HyouKash"><code>@​HyouKash</code></a>, <a
href="https://github.com/AdrienIT"><code>@​AdrienIT</code></a>, authored
by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a></p>
<h3>Runtime, Tooling, SDK</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md">github.com/open-policy-agent/opa's
changelog</a>.</em></p>
<blockquote>
<h2>1.4.2</h2>
<p>This is a bug fix release addressing the missing
<code>capabilities/v1.4.1.json</code> in the v1.4.1 release.</p>
<h2>1.4.1</h2>
<p>This is a security fix release for the fixes published in Go <a
href="https://groups.google.com/g/golang-announce/c/4t3lzH3I0eI">1.24.1</a>
and <a
href="https://groups.google.com/g/golang-announce/c/Y2uBTVKjBQk">1.24.2</a></p>
<ul>
<li>build: bump go to 1.24.2 (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7544">#7544</a>)
(authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a>)
Addressing <code>CVE-2025-22870</code> and <code>CVE-2025-22871</code>
vulnerabilities in the Go runtime.</li>
</ul>
<h2>1.4.0</h2>
<p>This release contains a security fix addressing CVE-2025-46569.
It also includes a mix of new features, bugfixes, and dependency
updates.</p>
<h4>Security Fix: CVE-2025-46569 - OPA server Data API HTTP path
injection of Rego (<a
href="https://github.com/open-policy-agent/opa/security/advisories/GHSA-6m8w-jc87-6cr7">GHSA-6m8w-jc87-6cr7</a>)</h4>
<p>A vulnerability in the OPA server's <a
href="https://www.openpolicyagent.org/docs/latest/rest-api/#data-api">Data
API</a> allows an attacker to craft the HTTP path in a way that injects
Rego code into the query that is evaluated.<br />
The evaluation result cannot be made to return any other data than what
is generated by the requested path, but this path can be misdirected,
and the injected Rego code can be crafted to make the query succeed or
fail; opening up for oracle attacks or, given the right circumstances,
erroneous policy decision results.
Furthermore, the injected code can be crafted to be computationally
expensive, resulting in a Denial Of Service (DoS) attack.</p>
<p><strong>Users are only impacted if all of the following
apply:</strong></p>
<ul>
<li>OPA is deployed as a standalone server (rather than being used as a
Go library)</li>
<li>The OPA server is exposed outside of the local host in an untrusted
environment.</li>
<li>The configured <a
href="https://www.openpolicyagent.org/docs/latest/security/#authentication-and-authorization">authorization
policy</a> does not do exact matching of the input.path attribute when
deciding if the request should be allowed.</li>
</ul>
<p><strong>or, if all of the following apply:</strong></p>
<ul>
<li>OPA is deployed as a standalone server.</li>
<li>The service connecting to OPA allows 3rd parties to insert
unsanitised text into the path of the HTTP request to OPA’s Data
API.</li>
</ul>
<p>Note: With <strong>no</strong> <a
href="https://www.openpolicyagent.org/docs/latest/security/#authentication-and-authorization">Authorization
Policy</a> configured for restricting API access (the default
configuration), the RESTful <a
href="https://www.openpolicyagent.org/docs/latest/rest-api/#data-api">Data
API</a> provides access for managing Rego policies; and the RESTful <a
href="https://www.openpolicyagent.org/docs/latest/rest-api/#query-api">Query
API</a> facilitates advanced queries.
Full access to these APIs provides both simpler, and broader access than
what the security issue describes here can facilitate.
As such, OPA servers exposed to a network are <strong>not</strong>
considered affected by the attack described here if they are knowingly
not restricting access through an Authorization Policy.</p>
<p>This issue affects all versions of OPA prior to 1.4.0.</p>
<p>See the <a
href="https://github.com/open-policy-agent/opa/security/advisories/GHSA-6m8w-jc87-6cr7">Security
Advisory</a> for more details.</p>
<p>Reported by <a
href="https://github.com/GamrayW"><code>@​GamrayW</code></a>, <a
href="https://github.com/HyouKash"><code>@​HyouKash</code></a>, <a
href="https://github.com/AdrienIT"><code>@​AdrienIT</code></a>, authored
by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a></p>
<h3>Runtime, Tooling, SDK</h3>
<ul>
<li>ast: Adding <code>rego_v1</code> feature to
<code>--v0-compatible</code> capabilities (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7474">#7474</a>)
authored by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a></li>
<li>executable: Add version and icon to OPA windows executable (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/3171">#3171</a>)
authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a> reported by
<a
href="https://github.com/christophwille"><code>@​christophwille</code></a></li>
<li>format: Don't panic on format due to unexpected comments (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/6330">#6330</a>)
authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a> reported by
<a href="https://github.com/sirpi"><code>@​sirpi</code></a></li>
<li>format: Avoid modifying strings when formatting (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/6220">#6220</a>)
authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a> reported by
<a href="https://github.com/zregvart"><code>@​zregvart</code></a></li>
<li>plugins/status: FIFO buffer channel for status events to prevent
slow status API blocking (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7522">#7522</a>)
authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/open-policy-agent/opa/commit/5e4582bb951f70641fe9ee85cc46245d079e5037"><code>5e4582b</code></a>
Prepare v1.4.2 release (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7547">#7547</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/3b64aff304139d6a84518813c54799d6d165f48d"><code>3b64aff</code></a>
Patch release v1.4.1 (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7545">#7545</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/8b0720247e65b97fe7715ca15682fee4040df4d1"><code>8b07202</code></a>
Prepare v1.4.0 release (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7541">#7541</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/ad2063247a14711882f18c387a511fc8094aa79c"><code>ad20632</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/24ff9cfb3ad0a6a5629f0b21458982d325ee03c5"><code>24ff9cf</code></a>
fix: return the raw strings when formatting (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7525">#7525</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/254f3bf0b9ee5faf1972ba31bbbe749bba19a000"><code>254f3bf</code></a>
fix(status plugin): make sure the latest status is read before manually
trigg...</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/9b5f6010c0503cd91eed8a56268a02d4895a42b4"><code>9b5f601</code></a>
docs: fix post merge badge (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7532">#7532</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/e4902774778da576da2a8f4b2fd50df6cc3da8b5"><code>e490277</code></a>
docs: Point path versioned requests to new sites (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7531">#7531</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/d65888c14f4cb2d67929590604415e35ba75f58c"><code>d65888c</code></a>
plugins/status: FIFO buffer channel for status events to prevent slow
status ...</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/eb77d10971ec772c3ac4968d4abe3666037d0338"><code>eb77d10</code></a>
docs: update edge links to use /docs/edge/ path (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7529">#7529</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/open-policy-agent/opa/compare/v1.3.0...v1.4.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/open-policy-agent/opa&package-manager=go_modules&previous-version=1.3.0&new-version=1.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 12:23:29 +00:00
dependabot[bot] 0832afbaf4 chore: bump gopkg.in/DataDog/dd-trace-go.v1 from 1.72.1 to 1.73.0 (#17763)
Bumps gopkg.in/DataDog/dd-trace-go.v1 from 1.72.1 to 1.73.0.

<details>
<summary>Most Recent Ignore Conditions Applied to This Pull
Request</summary>

| Dependency Name | Ignore Conditions |
| --- | --- |
| gopkg.in/DataDog/dd-trace-go.v1 | [>= 1.58.a, < 1.59] |
</details>


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=gopkg.in/DataDog/dd-trace-go.v1&package-manager=go_modules&previous-version=1.72.1&new-version=1.73.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 12:11:02 +00:00
dependabot[bot] 4f1df34981 chore: bump github.com/mark3labs/mcp-go from 0.25.0 to 0.27.0 (#17762)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.25.0 to 0.27.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.27.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Support audio content type in tools/call and prompts/get by <a
href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/250">mark3labs/mcp-go#250</a></li>
<li>refactor(server): extract common HTTP transport configuration
options by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/253">mark3labs/mcp-go#253</a></li>
<li>ci: add check to verify generated code is up-to-date by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/258">mark3labs/mcp-go#258</a></li>
<li>fix(MCPServer): correct notification method in func
<code>RemoveResource()</code> by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/262">mark3labs/mcp-go#262</a></li>
<li>Create sample client by <a
href="https://github.com/ezynda3"><code>@​ezynda3</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/265">mark3labs/mcp-go#265</a></li>
<li>Fix the issue where the 'Shutdown' method fails to properly exit. by
<a
href="https://github.com/uppercaveman"><code>@​uppercaveman</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/255">mark3labs/mcp-go#255</a></li>
<li>test(server): reliably detect Start/Shutdown deadlock in SSEServer
by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/264">mark3labs/mcp-go#264</a></li>
<li>docs: make code examples in the README correct as per spec by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/268">mark3labs/mcp-go#268</a></li>
<li>feat(MCPServer): avoid unnecessary notifications when Resource/Tool
not exists by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/266">mark3labs/mcp-go#266</a></li>
<li>chore: replace <code>interface{}</code> with <code>any</code> by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/261">mark3labs/mcp-go#261</a></li>
<li>fix(Srv/stdio): risk of goroutine leaks and concurrent reads in
<code>readNextLine()</code> by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/257">mark3labs/mcp-go#257</a></li>
<li>docs: Remove reference to <code>mcp.RoleSystem</code> by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/269">mark3labs/mcp-go#269</a></li>
<li>fix: fix some obvious simplifications by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/267">mark3labs/mcp-go#267</a></li>
<li>Optimization of listByPagination Performance by <a
href="https://github.com/qiangmzsx"><code>@​qiangmzsx</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/246">mark3labs/mcp-go#246</a></li>
<li>fix: properly marshal <code>ToolAnnotations</code> with
<code>false</code> values by <a
href="https://github.com/pottekkat"><code>@​pottekkat</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/260">mark3labs/mcp-go#260</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/uppercaveman"><code>@​uppercaveman</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/255">mark3labs/mcp-go#255</a></li>
<li><a href="https://github.com/pottekkat"><code>@​pottekkat</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/268">mark3labs/mcp-go#268</a></li>
<li><a href="https://github.com/qiangmzsx"><code>@​qiangmzsx</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/246">mark3labs/mcp-go#246</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.26.0...v0.27.0">https://github.com/mark3labs/mcp-go/compare/v0.26.0...v0.27.0</a></p>
<h2>Release v0.26.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(sse): Add <code>SessionWithTools</code> support to SSEServer by
<a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/232">mark3labs/mcp-go#232</a></li>
<li>Fix bug with MarshalJSON for NotificationParams by <a
href="https://github.com/Gelembjuk"><code>@​Gelembjuk</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/233">mark3labs/mcp-go#233</a></li>
<li>fix: write back error message if the response marshal failed by <a
href="https://github.com/ppzqh"><code>@​ppzqh</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/235">mark3labs/mcp-go#235</a></li>
<li>fix(server/sse): potential goroutine leak in Heartbeat sender by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/236">mark3labs/mcp-go#236</a></li>
<li>Fix stdio test compilation issues in CI by <a
href="https://github.com/ezynda3"><code>@​ezynda3</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/240">mark3labs/mcp-go#240</a></li>
<li>refactor(server/sse): rename WithBasePath to WithStaticBasePath by
<a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/238">mark3labs/mcp-go#238</a></li>
<li>fix(MCPServer): Session tool handler not used due to variable
shadowing by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/242">mark3labs/mcp-go#242</a></li>
<li>test: build mockstdio_server with isolated cache to prevent flaky CI
by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/241">mark3labs/mcp-go#241</a></li>
<li>fix: Use detached context for SSE message handling by <a
href="https://github.com/yash025"><code>@​yash025</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/244">mark3labs/mcp-go#244</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Gelembjuk"><code>@​Gelembjuk</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/233">mark3labs/mcp-go#233</a></li>
<li><a href="https://github.com/ppzqh"><code>@​ppzqh</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/235">mark3labs/mcp-go#235</a></li>
<li><a href="https://github.com/yash025"><code>@​yash025</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/244">mark3labs/mcp-go#244</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.25.0...v0.26.0">https://github.com/mark3labs/mcp-go/compare/v0.25.0...v0.26.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/e5121b37d7214e23c572e1b9a49ca5b8a4d648e4"><code>e5121b3</code></a>
Release v0.27.0</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/eeb7070c3dc7a3c1df64fe309a3b8433ea78096e"><code>eeb7070</code></a>
fix: properly marshal <code>ToolAnnotations</code> with
<code>false</code> values (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/260">#260</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/e1f1b4794ea047757a1272659b9c6a6d68826800"><code>e1f1b47</code></a>
optimize listByPagination (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/246">#246</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/46bfb6fbb69067de5513049479408732cbea5f33"><code>46bfb6f</code></a>
fix: fix some obvious simplifications (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/267">#267</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/716eabedfef62d99a04b749472b8cef27b404fa3"><code>716eabe</code></a>
docs: Remove reference to <code>mcp.RoleSystem</code> (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/269">#269</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/3dfa33164fe642a2adc8908c9d4794e8fb2cf806"><code>3dfa331</code></a>
fix(server/stdio): risk of concurrent reads and data loss in
readNextLine() (...</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/f8badd69d08f609cbbd7a218c3b2b8de05987277"><code>f8badd6</code></a>
chore: replace <code>interface{}</code> with <code>any</code> (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/261">#261</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/3442d321ad10a9edce5f2f76580e014a67de2229"><code>3442d32</code></a>
feat(MCPServer): avoid unnecessary notifications when Resource/Tool not
exist...</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/61b9784ea84d637e29a1bb2b226b953c4bdce4fe"><code>61b9784</code></a>
docs: make code examples in the README correct as per spec (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/268">#268</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/1c99eaf3bfa39f832e73ec26402b4c5fa62d0d16"><code>1c99eaf</code></a>
test(server): reliably detect Start/Shutdown deadlock in SSEServer (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/264">#264</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.25.0...v0.27.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.25.0&new-version=0.27.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 12:09:34 +00:00
dependabot[bot] 87152db05b ci: bump the github-actions group across 1 directory with 4 updates (#17760)
Bumps the github-actions group with 4 updates in the / directory:
[crate-ci/typos](https://github.com/crate-ci/typos),
[dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata),
[tj-actions/changed-files](https://github.com/tj-actions/changed-files)
and [github/codeql-action](https://github.com/github/codeql-action).

Updates `crate-ci/typos` from 1.31.1 to 1.32.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.32.0</h2>
<h2>[1.32.0] - 2025-05-02</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1264">April
2025</a> changes</li>
</ul>
<h2>v1.31.2</h2>
<h2>[1.31.2] - 2025-04-28</h2>
<h3>Fixes</h3>
<ul>
<li><em>(exclusion)</em> Don't confused emails as base64</li>
<li><em>(dict)</em> Correct <code>contamint</code> to
<code>contaminant</code>, not <code>contaminat</code></li>
<li><em>(dict)</em> Correct <code>contamints</code> to
<code>contaminants</code>, not <code>contaminats</code></li>
</ul>
<h3>Performance</h3>
<ul>
<li>Improve tokenization performance</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h1>Change Log</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>The format is based on <a href="http://keepachangelog.com/">Keep a
Changelog</a>
and this project adheres to <a href="http://semver.org/">Semantic
Versioning</a>.</p>
<!-- raw HTML omitted -->
<h2>[Unreleased] - ReleaseDate</h2>
<h2>[1.32.0] - 2025-05-02</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1264">April
2025</a> changes</li>
</ul>
<h2>[1.31.2] - 2025-04-28</h2>
<h3>Fixes</h3>
<ul>
<li><em>(exclusion)</em> Don't confused emails as base64</li>
<li><em>(dict)</em> Correct <code>contamint</code> to
<code>contaminant</code>, not <code>contaminat</code></li>
<li><em>(dict)</em> Correct <code>contamints</code> to
<code>contaminants</code>, not <code>contaminats</code></li>
</ul>
<h3>Performance</h3>
<ul>
<li>Improve tokenization performance</li>
</ul>
<h2>[1.31.1] - 2025-03-31</h2>
<h3>Fixes</h3>
<ul>
<li><em>(dict)</em> Also correct <code>typ</code> to
<code>type</code></li>
</ul>
<h2>[1.31.0] - 2025-03-28</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1248">March
2025</a> changes</li>
</ul>
<h2>[1.30.3] - 2025-03-24</h2>
<h3>Features</h3>
<ul>
<li>Support detecting <code>go.work</code> and <code>go.work.sum</code>
files</li>
</ul>
<h2>[1.30.2] - 2025-03-10</h2>
<h3>Features</h3>
<ul>
<li>Add <code>--highlight-words</code> and
<code>--highlight-identifiers</code> for easier debugging of config</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/crate-ci/typos/commit/0f0ccba9ed1df83948f0c15026e4f5ccfce46109"><code>0f0ccba</code></a>
chore: Release</li>
<li><a
href="https://github.com/crate-ci/typos/commit/5cb94233a615fb61c4500572b64d22425e96099a"><code>5cb9423</code></a>
chore: Release</li>
<li><a
href="https://github.com/crate-ci/typos/commit/2af8019e8687956766fbe303524b7f9b820885dd"><code>2af8019</code></a>
docs: Update changelog</li>
<li><a
href="https://github.com/crate-ci/typos/commit/970eb5442de8ea11b6b0e84904a11eda611a65db"><code>970eb54</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1291">#1291</a>
from epage/may</li>
<li><a
href="https://github.com/crate-ci/typos/commit/e84064f2d66ab3e807cfa29a1e203f78e56e115e"><code>e84064f</code></a>
feat(dict): April 2025 updates</li>
<li><a
href="https://github.com/crate-ci/typos/commit/8dddd500291130802cbb593827be9d862181402c"><code>8dddd50</code></a>
chore(deps): Update compatible (<a
href="https://redirect.github.com/crate-ci/typos/issues/1289">#1289</a>)</li>
<li><a
href="https://github.com/crate-ci/typos/commit/3be83342e28b9421997e9f781f713f8dde8453d2"><code>3be8334</code></a>
chore: Release</li>
<li><a
href="https://github.com/crate-ci/typos/commit/f16e5d44ec16bfba422e39e66c11d58fc1a3da76"><code>f16e5d4</code></a>
docs: Update changelog</li>
<li><a
href="https://github.com/crate-ci/typos/commit/e0927bd9d2433efaf2c8a998ad0434cb94304415"><code>e0927bd</code></a>
docs(action): Remove non-existent variables</li>
<li><a
href="https://github.com/crate-ci/typos/commit/2dbcebf645e8918080b28c7eb1f913143a3426da"><code>2dbcebf</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1287">#1287</a>
from epage/dict</li>
<li>Additional commits viewable in <a
href="https://github.com/crate-ci/typos/compare/b1a1ef3893ff35ade0cfa71523852a49bfd05d19...0f0ccba9ed1df83948f0c15026e4f5ccfce46109">compare
view</a></li>
</ul>
</details>
<br />

Updates `dependabot/fetch-metadata` from 2.3.0 to 2.4.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dependabot/fetch-metadata/releases">dependabot/fetch-metadata's
releases</a>.</em></p>
<blockquote>
<h2>v2.4.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump actions/create-github-app-token from 1.11.0 to 1.11.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/598">dependabot/fetch-metadata#598</a></li>
<li>Bump <code>@​vercel/ncc</code> from 0.38.1 to 0.38.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/578">dependabot/fetch-metadata#578</a></li>
<li>Add missing <code>@octokit/request-error</code> to
<code>package.json</code> by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/605">dependabot/fetch-metadata#605</a></li>
<li>Bump to ESLint 9 by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/606">dependabot/fetch-metadata#606</a></li>
<li>Stop using a node16 devcontainer image by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/608">dependabot/fetch-metadata#608</a></li>
<li>Make typescript compile to <code>&quot;es2022&quot;</code> by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/609">dependabot/fetch-metadata#609</a></li>
<li>Bump the dev-dependencies group across 1 directory with 8 updates by
<a href="https://github.com/dependabot"><code>@​dependabot</code></a> in
<a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/607">dependabot/fetch-metadata#607</a></li>
<li>Tidy up examples slightly by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/611">dependabot/fetch-metadata#611</a></li>
<li>Fixup some anchor tags that weren't deeplinking by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/614">dependabot/fetch-metadata#614</a></li>
<li>Remove unnecessary hardcoding of <code>ref</code> by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/617">dependabot/fetch-metadata#617</a></li>
<li>Bump actions/create-github-app-token from 1.11.3 to 2.0.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/616">dependabot/fetch-metadata#616</a></li>
<li>Enable caching of <code>npm install</code>/<code>npm ci</code> for
<code>setup-node</code> action by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/618">dependabot/fetch-metadata#618</a></li>
<li>Add workflow to publish new version of immutable action on every
release by <a
href="https://github.com/jeffwidman"><code>@​jeffwidman</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/623">dependabot/fetch-metadata#623</a></li>
<li>Bump actions/create-github-app-token from 2.0.2 to 2.0.6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/621">dependabot/fetch-metadata#621</a></li>
<li>v2.4.0 by <a
href="https://github.com/fetch-metadata-action-automation"><code>@​fetch-metadata-action-automation</code></a>
in <a
href="https://redirect.github.com/dependabot/fetch-metadata/pull/594">dependabot/fetch-metadata#594</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dependabot/fetch-metadata/compare/v2...v2.4.0">https://github.com/dependabot/fetch-metadata/compare/v2...v2.4.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/08eff52bf64351f401fb50d4972fa95b9f2c2d1b"><code>08eff52</code></a>
v2.4.0 (<a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/594">#594</a>)</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/821b65425137ec0dd9fa4e4931297ce81a017ed7"><code>821b654</code></a>
Merge pull request <a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/621">#621</a>
from dependabot/dependabot/github_actions/actions/cre...</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/2c22a370e3e9f4d539470325c4c46acc607ef78e"><code>2c22a37</code></a>
Bump actions/create-github-app-token from 2.0.2 to 2.0.6</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/6ad01a0495c3f8488ba16705f5031cadde56c8ba"><code>6ad01a0</code></a>
Add workflow to publish new version of immutable action on every release
(<a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/623">#623</a>)</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/8ca800c1642f5e46fd4fe73c07af0e3baf1375d6"><code>8ca800c</code></a>
Enable caching of <code>npm install</code>/<code>npm ci</code> for
<code>setup-node</code> action (<a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/618">#618</a>)</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/67876354acc60aadf59dc57d46959117cee2b764"><code>6787635</code></a>
Merge pull request <a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/616">#616</a>
from dependabot/dependabot/github_actions/actions/cre...</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/a09d4affbb4e2c87349169de0a2ced55e3c27168"><code>a09d4af</code></a>
Bump actions/create-github-app-token from 1.11.3 to 2.0.2</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/3a5ce46470ca6c67f17694ac27f0db1caf53b518"><code>3a5ce46</code></a>
Remove unnecessary hardcoding of <code>ref</code> (<a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/617">#617</a>)</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/798f45cdc56b81396c637207204f29f0f55da017"><code>798f45c</code></a>
Fixup some anchor tags that weren't deeplinking (<a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/614">#614</a>)</li>
<li><a
href="https://github.com/dependabot/fetch-metadata/commit/6c031ac618d23a38e886535b1c8ea06caaf2a444"><code>6c031ac</code></a>
Tidy up examples slightly (<a
href="https://redirect.github.com/dependabot/fetch-metadata/issues/611">#611</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/dependabot/fetch-metadata/compare/d7267f607e9d3fb96fc2fbe83e0af444713e90b7...08eff52bf64351f401fb50d4972fa95b9f2c2d1b">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/changed-files` from
5426ecc3f5c2b10effaefbd374f0abdc6a571b2f to
480f49412651059a414a6a5c96887abb1877de8a
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/changed-files/blob/main/HISTORY.md">tj-actions/changed-files's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.4...v46.0.5">46.0.5</a>
- (2025-04-09)</h1>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li><strong>deps:</strong> Bump yaml from 2.7.0 to 2.7.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2520">#2520</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/ed68ef82c095e0d48ec87eccea555d944a631a4c">ed68ef8</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump typescript from 5.8.2 to 5.8.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2516">#2516</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/a7bc14b808f23d3b467a4079c69a81f1a4500fd5">a7bc14b</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump <code>@​types/node</code> from
22.13.11 to 22.14.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2517">#2517</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/3d751f6b6d84071a17e1b9cf4ed79a80a27dd0ab">3d751f6</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump eslint-plugin-prettier from 5.2.3 to
5.2.6 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2519">#2519</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/e2fda4ec3cb0bc2a353843cae823430b3124db8f">e2fda4e</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump ts-jest from 29.2.6 to 29.3.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2518">#2518</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/0bed1b1132ec4879a39a2d624cf82a00d0bcfa48">0bed1b1</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump github/codeql-action from 3.28.12 to
3.28.15 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2530">#2530</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/68024587dc36f49685c96d59d3f1081830f968bb">6802458</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/branch-names from 8.0.1 to
8.1.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2521">#2521</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/cf2e39e86bf842d1f9bc5bca56c0a6b207cca792">cf2e39e</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/verify-changed-files from
20.0.1 to 20.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2523">#2523</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6abeaa506a419f85fa9e681260b443adbeebb3d4">6abeaa5</a>)
- (dependabot[bot])</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2511">#2511</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/6f67ee9ac810f0192ea7b3d2086406f97847bcf9">6f67ee9</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.3...v46.0.4">46.0.4</a>
- (2025-04-03)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li>Bug modified_keys and changed_key outputs not set when no changes
detected (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2509">#2509</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6cb76d07bee4c9772c6882c06c37837bf82a04d3">6cb76d0</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<ul>
<li>Update readme (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2508">#2508</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/b74df86ccb65173a8e33ba5492ac1a2ca6b216fd">b74df86</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2506">#2506</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted -->
Co-authored-by: Tonye Jack <a
href="mailto:jtonye@ymail.com">jtonye@ymail.com</a> (<a
href="https://github.com/tj-actions/changed-files/commit/27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99">27ae6b3</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.2...v46.0.3">46.0.3</a>
- (2025-03-23)</h1>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2501">#2501</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/41e0de576a0f2b64d9f06f2773f539109e55a70a">41e0de5</a>)
- (github-actions[bot])</p>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2499">#2499</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/945787811a795cd840a1157ac590dd7827a05c8e">9457878</a>)
- (github-actions[bot])</p>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/changed-files/commit/480f49412651059a414a6a5c96887abb1877de8a"><code>480f494</code></a>
chore(deps): bump <code>@​actions/github</code> from 6.0.0 to 6.0.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2556">#2556</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/405524a214f00911f11de2cd3a9a36902ddafa52"><code>405524a</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.15.14 to
22.15.17 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2557">#2557</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/b6970c44e602dd27272fdfc4e3cf76054f721d15"><code>b6970c4</code></a>
chore(deps-dev): bump eslint-config-prettier from 10.1.2 to 10.1.5 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2558">#2558</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/11fe0a22639570798676000acac7be726130b5ee"><code>11fe0a2</code></a>
chore(deps): bump github/codeql-action from 3.28.16 to 3.28.17 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2551">#2551</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/e7b157b1c4ad44acfc8d9be14b8cd8f5058636e3"><code>e7b157b</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.15.3 to 22.15.10
(<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2552">#2552</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/9132e0305b2a924727467f54f064d30bc85d67c1"><code>9132e03</code></a>
chore(deps-dev): bump eslint-plugin-prettier from 5.2.6 to 5.4.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2553">#2553</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/4168bb487d5b82227665ab4ec90b67ce02691741"><code>4168bb4</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.15.0 to 22.15.3
(<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2548">#2548</a>)</li>
<li>See full diff in <a
href="https://github.com/tj-actions/changed-files/compare/5426ecc3f5c2b10effaefbd374f0abdc6a571b2f...480f49412651059a414a6a5c96887abb1877de8a">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action` from 3.28.16 to 3.28.17
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.28.17</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.17 - 02 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2872">#2872</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.17/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.28.17 - 02 May 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2872">#2872</a></li>
</ul>
<h2>3.28.16 - 23 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.1. <a
href="https://redirect.github.com/github/codeql-action/pull/2863">#2863</a></li>
</ul>
<h2>3.28.15 - 07 Apr 2025</h2>
<ul>
<li>Fix bug where the action would fail if it tried to produce a debug
artifact with more than 65535 files. <a
href="https://redirect.github.com/github/codeql-action/pull/2842">#2842</a></li>
</ul>
<h2>3.28.14 - 07 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.0. <a
href="https://redirect.github.com/github/codeql-action/pull/2838">#2838</a></li>
</ul>
<h2>3.28.13 - 24 Mar 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.12 - 19 Mar 2025</h2>
<ul>
<li>Dependency caching should now cache more dependencies for Java
<code>build-mode: none</code> extractions. This should speed up
workflows and avoid inconsistent alerts in some cases.</li>
<li>Update default CodeQL bundle version to 2.20.7. <a
href="https://redirect.github.com/github/codeql-action/pull/2810">#2810</a></li>
</ul>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<h2>3.28.10 - 21 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.5. <a
href="https://redirect.github.com/github/codeql-action/pull/2772">#2772</a></li>
<li>Address an issue where the CodeQL Bundle would occasionally fail to
decompress on macOS. <a
href="https://redirect.github.com/github/codeql-action/pull/2768">#2768</a></li>
</ul>
<h2>3.28.9 - 07 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.4. <a
href="https://redirect.github.com/github/codeql-action/pull/2753">#2753</a></li>
</ul>
<h2>3.28.8 - 29 Jan 2025</h2>
<ul>
<li>Enable support for Kotlin 2.1.10 when running with CodeQL CLI
v2.20.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2744">#2744</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/60168efe1c415ce0f5521ea06d5c2062adbeed1b"><code>60168ef</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2886">#2886</a>
from github/update-v3.28.17-97a2bfd2a</li>
<li><a
href="https://github.com/github/codeql-action/commit/0d5a3115da6459f8ab4333164184f8292c0c7a7f"><code>0d5a311</code></a>
Update changelog for v3.28.17</li>
<li><a
href="https://github.com/github/codeql-action/commit/97a2bfd2a3d26d458da69e548f7f859d6fca634d"><code>97a2bfd</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2872">#2872</a>
from github/update-bundle/codeql-bundle-v2.21.2</li>
<li><a
href="https://github.com/github/codeql-action/commit/9aba20e4c91fd8c3a71d5ab2bdeba0da11713864"><code>9aba20e</code></a>
Merge branch 'main' into update-bundle/codeql-bundle-v2.21.2</li>
<li><a
href="https://github.com/github/codeql-action/commit/81a9508deb02898c1a7be79bd5b49bb0ab9c787e"><code>81a9508</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2876">#2876</a>
from github/henrymercer/fix-diff-informed-multiple-a...</li>
<li><a
href="https://github.com/github/codeql-action/commit/1569f4c145413fbce7d6573c6ee9212d2612d27f"><code>1569f4c</code></a>
Disable diff-informed queries in code scanning config tests</li>
<li><a
href="https://github.com/github/codeql-action/commit/62fbeb66b359bfbdec7d4d96af8f68aece59b4db"><code>62fbeb6</code></a>
Merge branch 'main' into
henrymercer/fix-diff-informed-multiple-analyze</li>
<li><a
href="https://github.com/github/codeql-action/commit/f122d1dc9eb83b12dc16b38495b667a2dddfa6f9"><code>f122d1d</code></a>
Address test failures from computing temporary directory too early</li>
<li><a
href="https://github.com/github/codeql-action/commit/083772aae48a3be5654921bb6e6ccb00e0e1d563"><code>083772a</code></a>
Do not fail diff informed analyses when <code>analyze</code> is run
twice in the same job</li>
<li><a
href="https://github.com/github/codeql-action/commit/5db14d0471303d6eee1e2a51393f5ae1669b6703"><code>5db14d0</code></a>
Merge branch 'main' into update-bundle/codeql-bundle-v2.21.2</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/28deaeda66b76a05916b6923827895f2b14ab387...60168efe1c415ce0f5521ea06d5c2062adbeed1b">compare
view</a></li>
</ul>
</details>
<br />

<details>
<summary>Most Recent Ignore Conditions Applied to This Pull
Request</summary>

| Dependency Name | Ignore Conditions |
| --- | --- |
| crate-ci/typos | [>= 1.30.a, < 1.31] |
</details>


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-12 11:58:20 +00:00
Mathias Fredriksson 7af188bfc1 fix(agent): fix unexpanded devcontainer paths for agentcontainers (#17736)
Devcontainers were duplicated in the API because paths weren't
absolute, we now normalize them early on to keep it simple.

Updates #16424
2025-05-12 14:03:40 +03:00
Edward Angert bd659142c8 docs: add note about experiment_report_tasks to ai-coder/create-template (#17563)
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-09 21:00:18 +00:00
Bruno Quaresma 842bb1f014 chore: replace MUI icons - 6 (#17751)
1. Replaced CheckCircleOutlined with CircleCheckIcon (Lucide)
2. Replaced Close/CloseIcon with XIcon (Lucide)
3. Replaced DoNotDisturbOnOutlined with CircleMinusIcon (Lucide)
4. Replaced Sell with TagIcon (Lucide)
2025-05-09 17:07:57 -03:00
Bruno Quaresma 1adad418ad feat: display user apps in the workspaces table (#17744)
Related to https://github.com/coder/coder/issues/17311

**Demo:**
<img width="1511" alt="Screenshot 2025-05-09 at 11 46 59"
src="https://github.com/user-attachments/assets/3e9ba618-ed5d-4eeb-996f-d7bcceb9f1a9"
/>
2025-05-09 17:01:57 -03:00
Bruno Quaresma 4970fb9bfa chore: replace MUI icons - 4 (#17748)
1. Replaced CloudUploadOutlined with CloudUploadIcon in FileUpload.tsx
2. Replaced DeleteOutline with TrashIcon in:
    - WorkspaceTopbar.tsx
    - TokensPageView.tsx
    - GroupPage.tsx
3. Replaced FolderOutlined with FolderIcon in FileUpload.tsx
2025-05-09 15:57:28 -03:00
Bruno Quaresma aa4b764025 chore: replace MUI icons - 3 (#17733)
1. Replaced TaskAlt with CircleCheckBigIcon in:
   - Paywall.tsx
   - PopoverPaywall.tsx
  
2. Replaced InfoOutlined with InfoIcon in:
   - ChangeVersionDialog.tsx
   - WorkspaceNotifications.tsx
   - Pill.stories.tsx
   
3. Replaced ErrorOutline/ErrorOutlineIcon with CircleAlertIcon in:
   - workspace.tsx
   - WorkspaceStatusBadge.tsx
   - AppLink.tsx
2025-05-09 15:09:03 -03:00
Bruno Quaresma b0a4ef01a8 chore: replace MUI icons - 2 (#17732)
Replace icons: 

Check | CheckIcon
KeyboardArrowDown | ChevronDownIcon
KeyboardArrowUp | ChevronUpIcon
2025-05-09 14:44:10 -03:00
Bruno Quaresma 9e44f18b4b refactor: add safe list for external app protocols (#17742)
To prevent malicious apps and vendors to use the Coder session token we
are adding safe protocols/schemas we want to support.

- vscode:
- vscode-insiders:
- windsurf:
- cursor:
- jetbrains-gateway:
- jetbrains:

Fix https://github.com/coder/security/issues/77
2025-05-09 14:40:26 -03:00
Edward Angert 5c532779af docs: clarify parameter autofill documentation (#17728)
closes #17706 

Clarify that:
1. URL query parameters work without experiment flag
2. The 'populate recently used parameters' feature still requires the
auto-fill-parameters experiment flag

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-09 13:01:11 -04:00
Danny Kopping 3ee95f14ce chore: upgrade terraform-provider-coder & preview libs (#17738)
The changes in `coder/preview` necessitated the changes in
`codersdk/richparameters.go` & `provisioner/terraform/resources.go`.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
2025-05-09 17:41:19 +02:00
Bruno Quaresma 9d7630bf4b chore: replace MUI icons - 1 (#17731)
1. Replaced MUI StopOutlined with Lucide SquareIcon in:
    - workspace.tsx
    - WorkspacesPageView.tsx
    - BuildIcon.tsx
    
 2. Replaced MUI PlayArrowOutlined with Lucide PlayIcon in:
    - workspace.tsx
    - WorkspacesPageView.tsx
    - BuildIcon.tsx
    
 3. Replaced MUI DeleteOutlined with Lucide TrashIcon in:
    - WorkspacesPageView.tsx
    - WorkspaceActions.tsx
    - TemplatePageHeader.tsx
    - BuildIcon.tsx
2025-05-09 11:16:46 -03:00
Bruno Quaresma 0b8fd7e403 chore: fix :first-child warning (#17727)
Fix the following warning:

```
The pseudo class ":first-child" is potentially unsafe when doing server-side rendering.
```
2025-05-09 11:11:00 -03:00
Bruno Quaresma 902c34cf01 refactor: improve apps.ts readbility (#17741)
Apply PR comments from https://github.com/coder/coder/pull/17724
2025-05-09 11:01:35 -03:00
Bruno Quaresma 2bdd035873 chore: add keys for each app on workspaces table (#17726)
Fix warning:
```
hook.js:608 Warning: Each child in a list should have a unique "key" prop.
```
2025-05-09 11:01:24 -03:00
Bruno Quaresma f897981e78 chore: extract app access logic for reuse (#17724)
We are starting to add app links in many places in the UI, and to make
it consistent, this PR extracts the most core logic into the
modules/apps for reuse.

Related to https://github.com/coder/coder/issues/17311
2025-05-09 10:41:52 -03:00
Michael Suchacz 2696926003 fix: fixed flaking VPN tunnel tests & bump coder/quartz to 0.1.3 (#17737)
Closes: https://github.com/coder/internal/issues/624
2025-05-09 12:27:47 +02:00
Danny Kopping 58adc629fa chore: add prebuild docs (#17580)
Partially addresses https://github.com/coder/internal/issues/593
2025-05-09 07:26:35 +00:00
Jon Ayers a9f1a6b2a2 fix: revert fix: persist terraform modules during template import (#17665) (#17734)
This reverts commit ae3d90b057.
2025-05-08 22:03:08 -04:00
ケイラ ae3d90b057 fix: persist terraform modules during template import (#17665) 2025-05-08 16:13:46 -06:00
Edward Angert 9a052e2a4c fix: use file filter in weekly-docs github action (#17729)
otherwise it ignores the instruction to only check docs/ when a file
changes in that dir

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-08 16:30:43 -04:00
Steven Masley d5360a6da0 chore: fetch workspaces by username with organization permissions (#17707)
Closes https://github.com/coder/coder/issues/17691

`ExtractOrganizationMembersParam` will allow fetching a user with only
organization permissions. If the user belongs to 0 orgs, then the user "does not exist" 
from an org perspective. But if you are a site-wide admin, then the user does exist.
2025-05-08 14:41:17 -05:00
Jaayden Halko d93a9cfde2 feat: add TagInput component for dynamic parameters (#17719)
resolves coder/preview#50

This uses the existing MultiTextField component as the tag-select
component for Dynamic parameters.

The intention is not to completely re-write the MultiTextField but to
make some design improvements to match the updated design patterns. This
should still work with the existing non-experimental
CreateWorkspacePage.

Before
<img width="556" alt="Screenshot 2025-05-08 at 12 58 31"
src="https://github.com/user-attachments/assets/9bf5bbf8-e26d-4523-8b5f-e4234e83d192"
/>


After
<img width="548" alt="Screenshot 2025-05-08 at 12 43 28"
src="https://github.com/user-attachments/assets/9fa90795-b2a9-4c07-b90e-938219202799"
/>
2025-05-08 12:59:33 -04:00
Jaayden Halko 0b141c47cb chore: add DynamicParameter stories (#17710)
resolves coder/preview#112

- Add stories for DynamicParameter component
- fix bug with displaying immutable badge and required asterisk
2025-05-08 10:12:05 -04:00
brettkolodny c5c3a54fca fix: create ssh directory if it doesn't already exist when running coder config-ssh (#17711)
Closes
[coder/internal#623](https://github.com/coder/internal/issues/623)

> [!WARNING]  
> PR co-authored by Claude Code
2025-05-08 10:10:52 -04:00
Vincent Vielle 1bb96b8528 fix: resolve flake test on manager (#17702)
Fixes coder/internal#544

---------

Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2025-05-08 16:49:57 +03:00
Bruno Quaresma 857587b35d fix: do not share token with http app urls (#17720)
It's a security issue to share the API token, and the protocols that we
actually want to share it with are not HTTP and handled locally on the
same machine.
 
Security issue introduced by https://github.com/coder/coder/pull/17708
2025-05-08 09:51:10 -03:00
Bruno Quaresma 4341403346 chore: simplify workspaces data fetching (#17703)
We've been using an abstraction that was not necessary to fetch
workspaces data. I also took sometime to use the new useWorkspaceUpdate
hook in the update workspace tooltip that was missing some important
steps like confirmation.
2025-05-08 09:42:39 -03:00
Bruno Quaresma 2695f4e950 chore: improve variable names of mocked users (#17701)
Many times I got confused when using MockUser and MockUser2 so I just
decided to better naming them to MockUserOwner and MockUserMember.
2025-05-08 09:32:32 -03:00
Jaayden Halko c66e80e862 fix: extract checkbox label from dynamic parameter styling prop (#17651)
resolves #17474 

A label will only be shown next to the checkbox If there is a value for
`label` in the styling prop for the dynamic parameter



<img width="457" alt="Screenshot 2025-05-01 at 21 35 32"
src="https://github.com/user-attachments/assets/3b3a8160-65a2-4411-b763-0d07a4eeb699"
/>
2025-05-08 08:02:27 -04:00
Dean Sheather b6182fe054 chore: add code-insiders.svg static icon (#17716)
We have `code.svg` but not `code-insiders.svg`
2025-05-08 05:09:16 +00:00
Steven Masley e4c6c10369 chore: fix comment regarding provisioner api version release (#17705)
See
https://github.com/coder/coder/commit/bc609d0056adeb11b1d2dc282db4d0ad20f3444b
2025-05-07 15:05:00 -05:00
Bruno Quaresma a02ba6616b fix: fill session token when app is external (#17708)
Fix https://github.com/coder/coder/issues/17704

During the [refactoring of WorkspaceApp response
type](https://github.com/coder/coder/pull/17700/files#diff-a7e67944708c3c914a24a02d515a89ecd414bfe61890468dac08abde55ba8e96R112),
I updated the logic to check if the session token should be injected
causing external apps to not load correctly.

To also avoid future confusions, we are only going to rely on the
`app.external` prop to open apps externally instead of verifying if the
URL does not use the HTTP protocol. I did some research and I didn't
find out a use case where it would be a problem.

I'm going to refactor this code very soon to allow opening apps from the
workspaces page, so I will write the tests to cover this use case there.

**Not included:**
During my next refactoring I'm also going to change the code to support
token injections directly in the HREF instead of making it happen during
the click event.
2025-05-07 19:59:52 +00:00
Thomas Kosiewski 29bce8d9e6 feat(cli): make MCP server work without user authentication (#17688)
Part of #17649

---

# Allow MCP server to run without authentication

This PR enhances the MCP server to operate without requiring authentication, making it more flexible for environments where authentication isn't available or necessary. Key changes:

- Replaced `InitClient` with `TryInitClient` to allow the MCP server to start without credentials
- Added graceful handling when URL or authentication is missing
- Made authentication status visible in server logs
- Added logic to skip user-dependent tools when no authenticated user is present
- Made the `coder_report_task` tool available with just an agent token (no user token required)
- Added comprehensive tests to verify operation without authentication

These changes allow the MCP server to function in more environments while still using authentication when available, improving flexibility for CI/CD and other automated environments.
2025-05-07 21:53:06 +02:00
Bruno Quaresma 6ac1bd807c feat: display builtin apps on workspaces table (#17695)
Related to https://github.com/coder/coder/issues/17311

<img width="1624" alt="Screenshot 2025-05-06 at 16 20 40"
src="https://github.com/user-attachments/assets/932f6034-9f8a-45d7-bf8d-d330dcca683d"
/>
2025-05-07 14:26:21 -03:00
Bruno Quaresma 9fe5b71d31 chore!: fix workspace apps response (#17700)
Fix WorkspaceApp response type to better reflect the schema from
https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app.
2025-05-07 10:05:07 -03:00
Bruno Quaresma d146115ca0 chore: update browser list db (#17699) 2025-05-07 09:01:47 -03:00
DevCats df0c6eda33 chore: add custom aider icon (#17682)
Created Custom SVG from Aider PNG and upload from module to static site
icons
2025-05-06 09:46:36 -07:00
Bruno Quaresma 4fa9d30bf4 refactor: update app buttons to use the new button component (#17684)
Related to https://github.com/coder/coder/issues/17311

- Replaces the MUI Buttons by the new shadcn/ui buttons. This change
allows the reuse of app links, and terminal buttons using the `asChild`
capability from the Radix components
- Uses the new [proposed
design](https://www.figma.com/design/OR75XeUI0Z3ksqt1mHsNQw/Workspace-views?node-id=1014-8242&t=wtUXJRN1SfyZiFKn-0)
- Updates the button styles to support image tags as icons
- Uses the new Tooltip component for the app buttons

**Before:**
<img width="1243" alt="Screenshot 2025-05-05 at 17 55 49"
src="https://github.com/user-attachments/assets/e689e9dc-d8e1-4c9d-ba09-ef1479a501f1"
/>

**After:**
<img width="1264" alt="Screenshot 2025-05-05 at 18 05 38"
src="https://github.com/user-attachments/assets/8fafbe20-f063-46ab-86cf-2e0381bba889"
/>
2025-05-06 13:26:37 -03:00
Hugo Dutka a7e828593f chore: retry failing tests in CI (#17681)
This PR introduces failing test retries in CI for e2e tests, Go tests
with the in-memory database, Go tests with Postgres, and the CLI tests.
Retries are not enabled for race tests.

The goal is to reduce how often flakes disrupt developers' workflows.
2025-05-06 16:53:26 +02:00
Bruno Quaresma d9b00e4849 feat: add inline actions into workspaces table (#17636)
Related to https://github.com/coder/coder/issues/17311

This PR adds inline actions in the workspaces page. It is a bit
different of the [original
design](https://www.figma.com/design/OR75XeUI0Z3ksqt1mHsNQw/Workspace-views?node-id=656-3979&m=dev)
because I'm splitting the work into three phases that I will explain in
more details in the demo.



https://github.com/user-attachments/assets/6383375e-ed10-45d1-b5d5-b4421e86d158
2025-05-06 11:28:14 -03:00
Michael Suchacz 5f516ed135 feat: improve coder connect tunnel handling on reconnect (#17598)
Closes https://github.com/coder/internal/issues/563

The [Coder Connect
tunnel](https://github.com/coder/coder/blob/main/vpn/tunnel.go) receives
workspace state from the Coder server over a [dRPC
stream.](https://github.com/coder/coder/blob/114ba4593b2a82dfd41cdcb7fd6eb70d866e7b86/tailnet/controllers.go#L1029)
When first connecting to this stream, the current state of the user's
workspaces is received, with subsequent messages being diffs on top of
that state.

However, if the client disconnects from this stream, such as when the
user's device is suspended, and then reconnects later, no mechanism
exists for the tunnel to differentiate that message containing the
entire initial state from another diff, and so that state is incorrectly
applied as a diff.

In practice:
- Tunnel connects, receives a workspace update containing all the
existing workspaces & agents.
- Tunnel loses connection, but isn't completely stopped.
- All the user's workspaces are restarted, producing a new set of
agents.
- Tunnel regains connection, and receives a workspace update containing
all the existing workspaces & agents.
- This initial update is incorrectly applied as a diff, with the
Tunnel's state containing both the old & new agents.

This PR introduces a solution in which tunnelUpdater, when created,
sends a FreshState flag with the WorkspaceUpdate type. This flag is
handled in the vpn tunnel in the following fashion:
- Preserve existing Agents
- Remove current Agents in the tunnel that are not present in the
WorkspaceUpdate
- Remove unreferenced Workspaces
2025-05-06 16:00:16 +02:00
Mathias Fredriksson ebad5c3ed0 test(agent): fix channel timeout in TestNewServer_CloseActiveConnections (#17690)
This fixes a test issue where we were waiting on a channel indefinitely
and the test timed out instead of failing due to earlier error.

Updates coder/internal#558
2025-05-06 11:20:28 +00:00
Jaayden Halko ec003b7cf9 fix: update default value handling for dynamic defaults (#17609)
resolves coder/preview#102
2025-05-06 06:40:31 -04:00
Jaayden Halko 4587082fcf chore: update design of External auth section of CreateWorkspacePage (#17683)
contributes to coder/preview#59

Figma:
https://www.figma.com/design/SMg6H8VKXnPSkE6h9KPoAD/UX-Presets?node-id=2180-2995&t=RL6ICIf6KUL5YUpB-1

This updates the design of the External authentication section of the
create workspace page form for both the existing and the new
experimental create workspace pages.

<img width="819" alt="Screenshot 2025-05-05 at 18 15 28"
src="https://github.com/user-attachments/assets/8bc419dc-e1db-4188-b920-73010bbe626d"
/>
2025-05-05 17:13:39 -04:00
Hugo Dutka 6b4d3f83bc chore: reduce "Upload tests to datadog" times in CI (#17668)
This PR speeds up the "Upload tests to datadog" step by downloading the
`datadog-ci` binary directly from GitHub releases. Most of the time used
to be spent in `npm install`, which consistently timed out on Windows
after a minute. [Now it takes 3
seconds](https://github.com/coder/coder/actions/runs/14834976784/job/41644230049?pr=17668#step:10:1).

I updated it to version v2.48.0 because v2.21.0 didn't have the
artifacts for arm64 macOS.
2025-05-05 18:49:58 +02:00
Ethan 4369765996 test: fix TestWorkspaceAgentReportStats flake (#17678)
Closes https://github.com/coder/internal/issues/609.

As seen in the below logs, the `last_used_at` time was updating, but just to the same value that it was on creation; `dbtime.Now` was called in quick succession. 

```
 t.go:106: 2025-05-05 12:11:54.166 [info]  coderd.workspace_usage_tracker: updated workspaces last_used_at  count=1  now="2025-05-05T12:11:54.161329Z"
    t.go:106: 2025-05-05 12:11:54.172 [debu]  coderd: GET  host=localhost:50422  path=/api/v2/workspaces/745b7ff3-47f2-4e1a-9452-85ea48ba5c46  proto=HTTP/1.1  remote_addr=127.0.0.1  start="2025-05-05T12:11:54.1669073Z"  workspace_name=peaceful_faraday34  requestor_id=b2cf02ae-2181-480b-bb1f-95dc6acb6497  requestor_name=testuser  requestor_email=""  took=5.2105ms  status_code=200  latency_ms=5  params_workspace=745b7ff3-47f2-4e1a-9452-85ea48ba5c46  request_id=7fd5ea90-af7b-4104-91c5-9ca64bc2d5e6
    workspaceagentsrpc_test.go:70: 
        	Error Trace:	C:/actions-runner/coder/coder/coderd/workspaceagentsrpc_test.go:70
        	Error:      	Should be true
        	Test:       	TestWorkspaceAgentReportStats
        	Messages:   	2025-05-05 12:11:54.161329 +0000 UTC is not after 2025-05-05 12:11:54.161329 +0000 UTC
```

If we change the initial `LastUsedAt` time to be a time in the past, ticking with a `dbtime.Now` will always update it to a later value. If it never updates, the condition will still fail.
2025-05-06 00:15:24 +10:00
Bruno Quaresma 93a584b7c2 fix: fix windsurf icon on light theme (#17679) 2025-05-05 11:10:50 -03:00
dependabot[bot] b8137e7ca4 chore: bump github.com/openai/openai-go from 0.1.0-beta.6 to 0.1.0-beta.10 (#17677)
Bumps [github.com/openai/openai-go](https://github.com/openai/openai-go)
from 0.1.0-beta.6 to 0.1.0-beta.10.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/openai/openai-go/releases">github.com/openai/openai-go's
releases</a>.</em></p>
<blockquote>
<h2>v0.1.0-beta.10</h2>
<h2>0.1.0-beta.10 (2025-04-14)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.9...v0.1.0-beta.10">v0.1.0-beta.9...v0.1.0-beta.10</a></p>
<h3>Chores</h3>
<ul>
<li><strong>internal:</strong> expand CI branch coverage (<a
href="https://redirect.github.com/openai/openai-go/issues/369">#369</a>)
(<a
href="https://github.com/openai/openai-go/commit/258dda8007a69b9c2720b225ee6d27474d676a93">258dda8</a>)</li>
<li><strong>internal:</strong> reduce CI branch coverage (<a
href="https://github.com/openai/openai-go/commit/a2f7c03eb984d98f29f908df103ea1743f2e3d9a">a2f7c03</a>)</li>
</ul>
<h2>v0.1.0-beta.9</h2>
<h2>0.1.0-beta.9 (2025-04-09)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-%5Bgo/compare/v0.1.0-beta.8...v0.1.0-beta.9%5D(https://www.golinks.io/compare/v0.1.0-beta.8...v0.1.0-beta.9?trackSource=github)">v0.1.0-beta.8...v0.1.0-beta.9</a></p>
<h3>Chores</h3>
<ul>
<li>workaround build errors (<a
href="https://redirect.github.com/openai/openai-%5Bgo/issues/366%5D(https://www.golinks.io/issues/366?trackSource=github)">#366</a>)
(<a
href="https://github.com/openai/openai-%5Bgo/commit/adeb003cab8efbfbf4424e03e96a0f5e728551cb%5D(https://www.golinks.io/commit/adeb003cab8efbfbf4424e03e96a0f5e728551cb?trackSource=github)">adeb003</a>)</li>
</ul>
<h2>v0.1.0-beta.8</h2>
<h2>0.1.0-beta.8 (2025-04-09)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.7...v0.1.0-beta.8">v0.1.0-beta.7...v0.1.0-beta.8</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> Add evalapi to sdk (<a
href="https://redirect.github.com/openai/openai-go/issues/360">#360</a>)
(<a
href="https://github.com/openai/openai-go/commit/88977d1868dbbe0060c56ba5dac8eb19773e4938">88977d1</a>)</li>
<li><strong>api:</strong> manual updates (<a
href="https://redirect.github.com/openai/openai-go/issues/363">#363</a>)
(<a
href="https://github.com/openai/openai-go/commit/5d068e0053172db7f5b75038aa215eee074eeeed">5d068e0</a>)</li>
<li><strong>client:</strong> add escape hatch to omit required param
fields (<a
href="https://redirect.github.com/openai/openai-go/issues/354">#354</a>)
(<a
href="https://github.com/openai/openai-go/commit/9690d6b49f8b00329afc038ec15116750853e620">9690d6b</a>)</li>
<li><strong>client:</strong> support custom http clients (<a
href="https://redirect.github.com/openai/openai-go/issues/357">#357</a>)
(<a
href="https://github.com/openai/openai-go/commit/b5a624f658cad774094427b36b05e446b41e8c52">b5a624f</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>docs:</strong> readme improvements (<a
href="https://redirect.github.com/openai/openai-go/issues/356">#356</a>)
(<a
href="https://github.com/openai/openai-go/commit/b2f8539d6316e3443aa733be2c95926696119c13">b2f8539</a>)</li>
<li><strong>internal:</strong> fix examples (<a
href="https://redirect.github.com/openai/openai-go/issues/361">#361</a>)
(<a
href="https://github.com/openai/openai-go/commit/de398b453d398299eb80c15f8fdb2bcbef5eeed6">de398b4</a>)</li>
<li><strong>internal:</strong> skip broken test (<a
href="https://redirect.github.com/openai/openai-go/issues/362">#362</a>)
(<a
href="https://github.com/openai/openai-go/commit/cccead9ba916142ac8fbe6e8926d706511e32ae3">cccead9</a>)</li>
<li><strong>tests:</strong> improve enum examples (<a
href="https://redirect.github.com/openai/openai-go/issues/359">#359</a>)
(<a
href="https://github.com/openai/openai-go/commit/e0b9739920114d6e991d3947b67fdf62cfaa09c7">e0b9739</a>)</li>
</ul>
<h2>v0.1.0-beta.7</h2>
<h2>0.1.0-beta.7 (2025-04-07)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.6...v0.1.0-beta.7">v0.1.0-beta.6...v0.1.0-beta.7</a></p>
<h3>Features</h3>
<ul>
<li><strong>client:</strong> make response union's AsAny method type
safe (<a
href="https://redirect.github.com/openai/openai-go/issues/352">#352</a>)
(<a
href="https://github.com/openai/openai-go/commit/1252f56c917e57d6d2b031501b2ff5f89f87cf87">1252f56</a>)</li>
</ul>
<h3>Chores</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/openai/openai-go/blob/main/CHANGELOG.md">github.com/openai/openai-go's
changelog</a>.</em></p>
<blockquote>
<h2>0.1.0-beta.10 (2025-04-14)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.9...v0.1.0-beta.10">v0.1.0-beta.9...v0.1.0-beta.10</a></p>
<h3>Chores</h3>
<ul>
<li><strong>internal:</strong> expand CI branch coverage (<a
href="https://redirect.github.com/openai/openai-go/issues/369">#369</a>)
(<a
href="https://github.com/openai/openai-go/commit/258dda8007a69b9c2720b225ee6d27474d676a93">258dda8</a>)</li>
<li><strong>internal:</strong> reduce CI branch coverage (<a
href="https://github.com/openai/openai-go/commit/a2f7c03eb984d98f29f908df103ea1743f2e3d9a">a2f7c03</a>)</li>
</ul>
<h2>0.1.0-beta.9 (2025-04-09)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.8...v0.1.0-beta.9">v0.1.0-beta.8...v0.1.0-beta.9</a></p>
<h3>Chores</h3>
<ul>
<li>workaround build errors (<a
href="https://redirect.github.com/openai/openai-go/issues/366">#366</a>)
(<a
href="https://github.com/openai/openai-go/commit/adeb003cab8efbfbf4424e03e96a0f5e728551cb">adeb003</a>)</li>
</ul>
<h2>0.1.0-beta.8 (2025-04-09)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.7...v0.1.0-beta.8">v0.1.0-beta.7...v0.1.0-beta.8</a></p>
<h3>Features</h3>
<ul>
<li><strong>api:</strong> Add evalapi to sdk (<a
href="https://redirect.github.com/openai/openai-go/issues/360">#360</a>)
(<a
href="https://github.com/openai/openai-go/commit/88977d1868dbbe0060c56ba5dac8eb19773e4938">88977d1</a>)</li>
<li><strong>api:</strong> manual updates (<a
href="https://redirect.github.com/openai/openai-go/issues/363">#363</a>)
(<a
href="https://github.com/openai/openai-go/commit/5d068e0053172db7f5b75038aa215eee074eeeed">5d068e0</a>)</li>
<li><strong>client:</strong> add escape hatch to omit required param
fields (<a
href="https://redirect.github.com/openai/openai-go/issues/354">#354</a>)
(<a
href="https://github.com/openai/openai-go/commit/9690d6b49f8b00329afc038ec15116750853e620">9690d6b</a>)</li>
<li><strong>client:</strong> support custom http clients (<a
href="https://redirect.github.com/openai/openai-go/issues/357">#357</a>)
(<a
href="https://github.com/openai/openai-go/commit/b5a624f658cad774094427b36b05e446b41e8c52">b5a624f</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>docs:</strong> readme improvements (<a
href="https://redirect.github.com/openai/openai-go/issues/356">#356</a>)
(<a
href="https://github.com/openai/openai-go/commit/b2f8539d6316e3443aa733be2c95926696119c13">b2f8539</a>)</li>
<li><strong>internal:</strong> fix examples (<a
href="https://redirect.github.com/openai/openai-go/issues/361">#361</a>)
(<a
href="https://github.com/openai/openai-go/commit/de398b453d398299eb80c15f8fdb2bcbef5eeed6">de398b4</a>)</li>
<li><strong>internal:</strong> skip broken test (<a
href="https://redirect.github.com/openai/openai-go/issues/362">#362</a>)
(<a
href="https://github.com/openai/openai-go/commit/cccead9ba916142ac8fbe6e8926d706511e32ae3">cccead9</a>)</li>
<li><strong>tests:</strong> improve enum examples (<a
href="https://redirect.github.com/openai/openai-go/issues/359">#359</a>)
(<a
href="https://github.com/openai/openai-go/commit/e0b9739920114d6e991d3947b67fdf62cfaa09c7">e0b9739</a>)</li>
</ul>
<h2>0.1.0-beta.7 (2025-04-07)</h2>
<p>Full Changelog: <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.6...v0.1.0-beta.7">v0.1.0-beta.6...v0.1.0-beta.7</a></p>
<h3>Features</h3>
<ul>
<li><strong>client:</strong> make response union's AsAny method type
safe (<a
href="https://redirect.github.com/openai/openai-go/issues/352">#352</a>)
(<a
href="https://github.com/openai/openai-go/commit/1252f56c917e57d6d2b031501b2ff5f89f87cf87">1252f56</a>)</li>
</ul>
<h3>Chores</h3>
<ul>
<li><strong>docs:</strong> doc improvements (<a
href="https://redirect.github.com/openai/openai-go/issues/350">#350</a>)
(<a
href="https://github.com/openai/openai-go/commit/80debc824eaacb4b07c8f3e8b1d0488d860d5be5">80debc8</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/openai/openai-go/commit/c0414f15a9f4065adee2ed96a4dcd4d4cb9708aa"><code>c0414f1</code></a>
release: 0.1.0-beta.10</li>
<li><a
href="https://github.com/openai/openai-go/commit/192ec22bd758a045b2fe7304252c508b7a075e6d"><code>192ec22</code></a>
chore(internal): reduce CI branch coverage</li>
<li><a
href="https://github.com/openai/openai-go/commit/17cbc6d2c8ffbba0c9d19206b1f402010790ba2e"><code>17cbc6d</code></a>
chore(internal): expand CI branch coverage (<a
href="https://redirect.github.com/openai/openai-go/issues/369">#369</a>)</li>
<li><a
href="https://github.com/openai/openai-go/commit/e1d5123160f195fbb74e00548e8d7896db9caafc"><code>e1d5123</code></a>
release: 0.1.0-beta.9</li>
<li><a
href="https://github.com/openai/openai-go/commit/4e42dd39d9ad6d9deb8c75d9131fb636edf93ae9"><code>4e42dd3</code></a>
chore: workaround build errors (<a
href="https://redirect.github.com/openai/openai-go/issues/366">#366</a>)</li>
<li><a
href="https://github.com/openai/openai-go/commit/0ae103de4e01e5239788a56fca3d7621b83460ab"><code>0ae103d</code></a>
release: 0.1.0-beta.8</li>
<li><a
href="https://github.com/openai/openai-go/commit/68c32a0aec380926b962ed74d4002a883d012dcd"><code>68c32a0</code></a>
feat(api): manual updates (<a
href="https://redirect.github.com/openai/openai-go/issues/363">#363</a>)</li>
<li><a
href="https://github.com/openai/openai-go/commit/8599318b87e59ea0550da8c8451dd12c6716776f"><code>8599318</code></a>
chore(internal): skip broken test (<a
href="https://redirect.github.com/openai/openai-go/issues/362">#362</a>)</li>
<li><a
href="https://github.com/openai/openai-go/commit/5e86f0f2734a9898584a250b5052403172f331ba"><code>5e86f0f</code></a>
chore(internal): fix examples (<a
href="https://redirect.github.com/openai/openai-go/issues/361">#361</a>)</li>
<li><a
href="https://github.com/openai/openai-go/commit/4a496a7674de63d9fb838a5095a2958a7cbaa1f7"><code>4a496a7</code></a>
feat(api): Add evalapi to sdk (<a
href="https://redirect.github.com/openai/openai-go/issues/360">#360</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/openai/openai-go/compare/v0.1.0-beta.6...v0.1.0-beta.10">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/openai/openai-go&package-manager=go_modules&previous-version=0.1.0-beta.6&new-version=0.1.0-beta.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 12:54:22 +00:00
dependabot[bot] 1f569f71f8 chore: bump google.golang.org/api from 0.230.0 to 0.231.0 (#17671)
Bumps
[google.golang.org/api](https://github.com/googleapis/google-api-go-client)
from 0.230.0 to 0.231.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/releases">google.golang.org/api's
releases</a>.</em></p>
<blockquote>
<h2>v0.231.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.230.0...v0.231.0">0.231.0</a>
(2025-04-29)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3122">#3122</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/47cbba61ec8d62ebdfd1affe3a9244b20184c781">47cbba6</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3124">#3124</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/677b602b6f3f072ebfac6c5791cc06d15720b136">677b602</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3125">#3125</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/8ccf1f08977c7843d093bba21d391b082e206a75">8ccf1f0</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3126">#3126</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/405935174a0a7c9734c8e6b0dce487c481a7927e">4059351</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3127">#3127</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ae18b2206b6182d47d69227b638dfc42d975b889">ae18b22</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3129">#3129</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c33e0d153c99c931e5b953e3ccfa40fe8ac20c02">c33e0d1</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md">google.golang.org/api's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.230.0...v0.231.0">0.231.0</a>
(2025-04-29)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3122">#3122</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/47cbba61ec8d62ebdfd1affe3a9244b20184c781">47cbba6</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3124">#3124</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/677b602b6f3f072ebfac6c5791cc06d15720b136">677b602</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3125">#3125</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/8ccf1f08977c7843d093bba21d391b082e206a75">8ccf1f0</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3126">#3126</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/405935174a0a7c9734c8e6b0dce487c481a7927e">4059351</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3127">#3127</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ae18b2206b6182d47d69227b638dfc42d975b889">ae18b22</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3129">#3129</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c33e0d153c99c931e5b953e3ccfa40fe8ac20c02">c33e0d1</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/70d3b4f38ec8df290ddcaedb749eaf29f798958c"><code>70d3b4f</code></a>
chore(main): release 0.231.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3123">#3123</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/c33e0d153c99c931e5b953e3ccfa40fe8ac20c02"><code>c33e0d1</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3129">#3129</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/673da13c2fc8c8758ae8c1c1fc2d02fdb9556bc5"><code>673da13</code></a>
chore(all): update all (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3128">#3128</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/ae18b2206b6182d47d69227b638dfc42d975b889"><code>ae18b22</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3127">#3127</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/405935174a0a7c9734c8e6b0dce487c481a7927e"><code>4059351</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3126">#3126</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/8ccf1f08977c7843d093bba21d391b082e206a75"><code>8ccf1f0</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3125">#3125</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/677b602b6f3f072ebfac6c5791cc06d15720b136"><code>677b602</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3124">#3124</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/47cbba61ec8d62ebdfd1affe3a9244b20184c781"><code>47cbba6</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3122">#3122</a>)</li>
<li>See full diff in <a
href="https://github.com/googleapis/google-api-go-client/compare/v0.230.0...v0.231.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/api&package-manager=go_modules&previous-version=0.230.0&new-version=0.231.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 12:37:45 +00:00
dependabot[bot] dc66dafc7c chore: bump github.com/mark3labs/mcp-go from 0.23.1 to 0.25.0 (#17672)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.23.1 to 0.25.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.25.0</h2>
<h2>What's Changed</h2>
<ul>
<li>update doc comments to match Go conventions by <a
href="https://github.com/yinebebt"><code>@​yinebebt</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/226">mark3labs/mcp-go#226</a></li>
<li>fix: Add Accept Header in StreamableHTTP Client by <a
href="https://github.com/hhxiao"><code>@​hhxiao</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/230">mark3labs/mcp-go#230</a></li>
<li>fix(SSE): only initialize <code>http.Server</code> when not set by
<a href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/229">mark3labs/mcp-go#229</a></li>
<li>fix: Prevent panic in parsing functions for null results by <a
href="https://github.com/cocovs"><code>@​cocovs</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/218">mark3labs/mcp-go#218</a></li>
<li>[SSEClient] Add ability to override the http.Client by <a
href="https://github.com/sks"><code>@​sks</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/109">mark3labs/mcp-go#109</a></li>
<li>feat(SSEServer): add WithAppendQueryToMessageEndpoint() by <a
href="https://github.com/liut"><code>@​liut</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/136">mark3labs/mcp-go#136</a></li>
<li>feat: quick return tool-call request, send response via SSE in
goroutine by <a
href="https://github.com/CeerDecy"><code>@​CeerDecy</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/163">mark3labs/mcp-go#163</a></li>
<li>feat(server/sse): Add support for dynamic base paths by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/214">mark3labs/mcp-go#214</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/yinebebt"><code>@​yinebebt</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/226">mark3labs/mcp-go#226</a></li>
<li><a href="https://github.com/hhxiao"><code>@​hhxiao</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/230">mark3labs/mcp-go#230</a></li>
<li><a href="https://github.com/cocovs"><code>@​cocovs</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/218">mark3labs/mcp-go#218</a></li>
<li><a href="https://github.com/sks"><code>@​sks</code></a> made their
first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/109">mark3labs/mcp-go#109</a></li>
<li><a href="https://github.com/liut"><code>@​liut</code></a> made their
first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/136">mark3labs/mcp-go#136</a></li>
<li><a href="https://github.com/CeerDecy"><code>@​CeerDecy</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/163">mark3labs/mcp-go#163</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.24.1...v0.25.0">https://github.com/mark3labs/mcp-go/compare/v0.24.1...v0.25.0</a></p>
<h2>Release v0.24.1</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: marshal <code>ToolInputSchema.Properties</code> to {} when
len=0 by <a href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/225">mark3labs/mcp-go#225</a></li>
<li>fix(client/test): verify mock server binary exists after compilation
by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/215">mark3labs/mcp-go#215</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.24.0...v0.24.1">https://github.com/mark3labs/mcp-go/compare/v0.24.0...v0.24.1</a></p>
<h2>Release v0.24.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Use correct name in Go documentation by <a
href="https://github.com/oschwald"><code>@​oschwald</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/202">mark3labs/mcp-go#202</a></li>
<li>fix(client): resource leak in <code>SSEClient.SendRequest()</code>
by <a href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/206">mark3labs/mcp-go#206</a></li>
<li>fix(client): risk of resource leak and closing closed channel by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/208">mark3labs/mcp-go#208</a></li>
<li>no need to check empty text by <a
href="https://github.com/graydovee"><code>@​graydovee</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/209">mark3labs/mcp-go#209</a></li>
<li>refactor: Pull out <code>Annotations</code> structure rather than
being an anonymous inner struct by <a
href="https://github.com/rm-hull"><code>@​rm-hull</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/203">mark3labs/mcp-go#203</a></li>
<li>perf: optimize usage of RWMutex in MCPServer for performance by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/181">mark3labs/mcp-go#181</a></li>
<li>feat: Add server hooks:OnRequestInitialization by <a
href="https://github.com/AlexNiny"><code>@​AlexNiny</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/164">mark3labs/mcp-go#164</a></li>
<li>fix: Improve content type handling in streamable_http.go by <a
href="https://github.com/TBXark"><code>@​TBXark</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/210">mark3labs/mcp-go#210</a></li>
<li>Add <code>mcptest</code> package for in-process MCP testing by <a
href="https://github.com/octo"><code>@​octo</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/149">mark3labs/mcp-go#149</a></li>
<li>Manage tools on a per session basis by <a
href="https://github.com/ezynda3"><code>@​ezynda3</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/179">mark3labs/mcp-go#179</a></li>
<li>Fix: fix client sse tcp connection re-use by draining outstanding io
by <a href="https://github.com/bcain99"><code>@​bcain99</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/212">mark3labs/mcp-go#212</a></li>
<li>perf(server): release Mutex early for performance by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/213">mark3labs/mcp-go#213</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/oschwald"><code>@​oschwald</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/202">mark3labs/mcp-go#202</a></li>
<li><a href="https://github.com/graydovee"><code>@​graydovee</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/209">mark3labs/mcp-go#209</a></li>
<li><a href="https://github.com/rm-hull"><code>@​rm-hull</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/203">mark3labs/mcp-go#203</a></li>
<li><a href="https://github.com/AlexNiny"><code>@​AlexNiny</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/164">mark3labs/mcp-go#164</a></li>
<li><a href="https://github.com/octo"><code>@​octo</code></a> made their
first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/149">mark3labs/mcp-go#149</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/eadd7023515f7eaad5808720c157b1cc25581d90"><code>eadd702</code></a>
Format</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/4a1010e73b34db4a602a7f34e2690a3a51d963cb"><code>4a1010e</code></a>
feat(server/sse): Add support for dynamic base paths (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/214">#214</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/cfeb0eec85509f516064e3df007b625d4fc89f48"><code>cfeb0ee</code></a>
feat: quick return tool-call request, send response via SSE in goroutine
(<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/163">#163</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/d352118718f3f0481ff8484f5e9914ed26be5d38"><code>d352118</code></a>
feat(SSEServer): add WithAppendQueryToMessageEndpoint() (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/136">#136</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/df5f67eeb1841f4350b4079b643051364be7ed7b"><code>df5f67e</code></a>
[chore][client] Add ability to override the http.Client (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/109">#109</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/ddb59ddfadc950647316561afebe8060f6276880"><code>ddb59dd</code></a>
fix: handle nil rawMessage in response parsing functions (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/218">#218</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/f0a648b91d852442c1cd52f98391aa1fe1540b60"><code>f0a648b</code></a>
fix(SSE): only initialize http.Server when not set (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/229">#229</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/ffc63d90b0cb05ee26ced8880c329dadad4c202b"><code>ffc63d9</code></a>
Add Accept header (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/230">#230</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/ae96a68a47e6ad255b8e976e89c30ac595139511"><code>ae96a68</code></a>
fix: update doc comments to match Go conventions (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/226">#226</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/df736673ba674040abe5c2edbedd70455483d961"><code>df73667</code></a>
fix(client/test): verify mock server binary exists after compilation (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/215">#215</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.23.1...v0.25.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.23.1&new-version=0.25.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 12:37:32 +00:00
Hugo Dutka 87f4535357 chore: optimize CI setup time on Windows (#17666)
This PR focuses on optimizing go-test CI times on Windows. It:

- backs the `$RUNNER_TEMP` directory with a RAM disk. This directory is
used by actions like cache, setup-go, and setup-terraform as a staging
area
- backs `GOCACHE`, `GOMODCACHE`, and `GOPATH` with a RAM disk
- backs `$GITHUB_WORKSPACE` with a RAM disk - that's where the
repository is checked out
- uses preinstalled Go on Windows runners
- starts using the depot Windows runner

From what I've seen, these changes bring test times down to be on par
with Linux and macOS. The biggest improvement comes from backing
frequently accessed paths with RAM disks. The C drive is surprisingly
slow - I ran some performance tests with
[fio](https://fio.readthedocs.io/en/latest/fio_doc.html#) where I tested
IOPS on many small files, and the RAM disk was 100x faster.

Additionally, the depot runners seem to have more consistent performance
than the ones provided by GitHub.
2025-05-05 14:26:30 +02:00
Danny Kopping a646478aed fix: move pubsub publishing out of database transactions to avoid conn exhaustion (#17648)
Database transactions hold onto connections, and `pubsub.Publish` tries
to acquire a connection of its own. If the latter is called within a
transaction, this can lead to connection exhaustion.

I plan two follow-ups to this PR:

1. Make connection counts tuneable

https://github.com/coder/coder/blob/main/cli/server.go#L2360-L2376

We will then be able to write tests showing how connection exhaustion
occurs.

2. Write a linter/ruleguard to prevent `pubsub.Publish` from being
called within a transaction.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-05 11:54:18 +02:00
Bruno Quaresma 82fdb6a6ae fix: fix size for non-squared app icons (#17663)
**Before:**

![image](https://github.com/user-attachments/assets/e7544b00-24b0-405c-b763-49a9a009c1d2)

**After:**
<img width="192" alt="Screenshot 2025-05-02 at 14 36 19"
src="https://github.com/user-attachments/assets/59cb4531-06fd-44bc-b4b9-4441f2dce79a"
/>
2025-05-02 14:44:13 -03:00
Bruno Quaresma 3be6487f02 feat: support GFM alerts in markdown (#17662)
Closes https://github.com/coder/coder/issues/17660

Add support to [GFM
Alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts).

<img width="635" alt="Screenshot 2025-05-02 at 14 26 36"
src="https://github.com/user-attachments/assets/8b785e0f-87f4-4bbd-9107-67858ad5dece"
/>

PS: This was heavily copied from
https://github.com/coder/coder-registry/blob/dev/cmd/main/site/src/components/MarkdownView/MarkdownView.tsx
2025-05-02 14:44:01 -03:00
Cian Johnston 544259b809 feat: add database tables and API routes for agentic chat feature (#17570)
Backend portion of experimental `AgenticChat` feature:
- Adds database tables for chats and chat messages
- Adds functionality to stream messages from LLM providers using
`kylecarbs/aisdk-go`
- Adds API routes with relevant functionality (list, create, update
chats, insert chat message)
- Adds experiment `codersdk.AgenticChat`

---------

Co-authored-by: Kyle Carberry <kyle@carberry.com>
2025-05-02 17:29:57 +01:00
M Atif Ali 64b9bc1ca4 fix: update licensing info URL on sign up page (#17657) 2025-05-02 16:07:10 +00:00
Jaayden Halko e37ddd44d2 chore: improve the design of the create workspace page for dynamic parameters (#17654)
contributes to coder/preview#59

1. Improves the design and layout of the presets dropdown and switch
2. Improves the design for the immutable badge

<img width="537" alt="Screenshot 2025-05-01 at 23 28 11"
src="https://github.com/user-attachments/assets/f0967758-5ea7-4436-b44a-e014c048202c"
/>
<img width="714" alt="Screenshot 2025-05-01 at 23 28 34"
src="https://github.com/user-attachments/assets/0bb091e1-611f-4a58-8f6f-b3bb027c6a10"
/>
2025-05-02 11:14:32 -04:00
Edward Angert 912b6aba82 docs: link to eks steps from aws section (#17646)
closes #17634

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-02 15:13:42 +00:00
Edward Angert 50695b7d76 docs: fix link in tutorials faq to new docker-code-server link (#17655)
<https://github.com/sharkymark/v2-templates/tree/main/src/templates/docker/docker-code-server>

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-02 13:44:30 +00:00
Danny Kopping c278662218 feat: collect database metrics (#17635)
Currently we don't have a way to get insight into Postgres connections
being exhausted.

By using the prometheus' [`DBStats`
collector](https://github.com/prometheus/client_golang/blob/main/prometheus/collectors/dbstats_collector.go),
we get some insight out-of-the-box.

```
# HELP go_sql_idle_connections The number of idle connections.
# TYPE go_sql_idle_connections gauge
go_sql_idle_connections{db_name="coder"} 1
# HELP go_sql_in_use_connections The number of connections currently in use.
# TYPE go_sql_in_use_connections gauge
go_sql_in_use_connections{db_name="coder"} 2
# HELP go_sql_max_idle_closed_total The total number of connections closed due to SetMaxIdleConns.
# TYPE go_sql_max_idle_closed_total counter
go_sql_max_idle_closed_total{db_name="coder"} 112
# HELP go_sql_max_idle_time_closed_total The total number of connections closed due to SetConnMaxIdleTime.
# TYPE go_sql_max_idle_time_closed_total counter
go_sql_max_idle_time_closed_total{db_name="coder"} 0
# HELP go_sql_max_lifetime_closed_total The total number of connections closed due to SetConnMaxLifetime.
# TYPE go_sql_max_lifetime_closed_total counter
go_sql_max_lifetime_closed_total{db_name="coder"} 0
# HELP go_sql_max_open_connections Maximum number of open connections to the database.
# TYPE go_sql_max_open_connections gauge
go_sql_max_open_connections{db_name="coder"} 10
# HELP go_sql_open_connections The number of established connections both in use and idle.
# TYPE go_sql_open_connections gauge
go_sql_open_connections{db_name="coder"} 3
# HELP go_sql_wait_count_total The total number of connections waited for.
# TYPE go_sql_wait_count_total counter
go_sql_wait_count_total{db_name="coder"} 28
# HELP go_sql_wait_duration_seconds_total The total time blocked waiting for a new connection.
# TYPE go_sql_wait_duration_seconds_total counter
go_sql_wait_duration_seconds_total{db_name="coder"} 0.086936235
```

`go_sql_wait_count_total` is the metric I'm most interested in gaining,
but the others are also very useful.

Changing the prefix is easy (`prometheus.WrapRegistererWithPrefix`), but
getting rid of the `go_` segment is not quite so easy. I've kept the
changeset small for now.

**NOTE:** I imported a library to determine the database name from the
given conn string. It's [not as
simple](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)
as one might hope. The database name is used for the `db_name` label.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-02 12:17:01 +02:00
Jaayden Halko e718c3ab2f fix: improve WebSocket error handling in CreateWorkspacePageExperimental (#17647)
Refactor WebSocket error handling to ensure that errors are only set
when the current socket ref matches the active one. This prevents
unnecessary error messages when the WebSocket connection closes
unexpectedly

This solves the problem of showing error messages because of React
Strict mode rendering the page twice and opening 2 websocket
connections.
2025-05-01 19:02:34 -04:00
Mathias Fredriksson a226a75b32 docs: add early access dev container docs (#17613)
This change documents the early access dev containers integration and
how to enable it, what features are available and what limitations exist
at the time of writing.

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-05-01 23:45:02 +01:00
Yevhenii Shcherbina ef11d4f769 fix: fix bug with deletion of prebuilt workspaces (#17652)
Don't specify the template version for a delete transition, because the
prebuilt workspace may have been created using an older template
version.
If the template version isn't explicitly set, the builder will
automatically use the version from the last workspace build - which is
the desired behavior.
2025-05-01 17:26:30 -04:00
Jaayden Halko d9ef6ed8ae chore: replace MoreMenu with DropdownMenu (#17615)
Replace MoreMenu with DropDownMenu component to match update design
patterns.

Note: This was the result of experimentation using Cursor to make the
changes and Claude Code for fixing tests.

One key takeaway is that verbose e2e logging, especially benign
warnings/errors can confuse Claude Code in running playwright and
confirming its work.


<img width="201" alt="Screenshot 2025-05-01 at 00 00 52"
src="https://github.com/user-attachments/assets/4905582e-902e-4b61-adc8-14cab6bd006b"
/>
<img width="257" alt="Screenshot 2025-05-01 at 00 01 07"
src="https://github.com/user-attachments/assets/5befc420-724a-4c57-9a9d-330a39867fae"
/>
<img width="270" alt="Screenshot 2025-05-01 at 00 01 20"
src="https://github.com/user-attachments/assets/9cbf07cb-7d44-4228-ae6f-216e9f2faed0"
/>
<img width="224" alt="Screenshot 2025-05-01 at 00 01 30"
src="https://github.com/user-attachments/assets/9fe95916-3d9d-4600-9b1f-8a620e152a53"
/>
2025-05-01 13:14:11 -04:00
brettkolodny b7e08ba7c9 fix: filter out deleted users when attempting to delete an organization (#17621)
Closes
[coder/internal#601](https://github.com/coder/internal/issues/601)
2025-05-01 13:26:01 -03:00
Phorcys cae4fa8b45 chore: correct typo in "Logs" page (#17633)
I saw this typo when looking at the docs, quick fix.

https://coder.com/docs/admin/monitoring/logs
2025-05-01 12:14:27 -04:00
Cian Johnston 4ac71e9fd9 fix(codersdk/toolsdk): ensure all tools include required fields of aisdk.Schema (#17632) 2025-05-01 12:19:35 +00:00
Spike Curtis ef00ae54f4 fix: fix data race in agentscripts.Runner (#17630)
Fixes https://github.com/coder/internal/issues/604

Fixes a data race in `agentscripts.Runner` where a concurrent `Execute()` call races with `Init()`. We hit this race during shut down, which is not synchronized against starting up.

In this PR I've chosen to add synchronization to the `Runner` rather than try to synchronize the calls in the agent. When we close down the agent, it's OK to just throw an error if we were never initialized with a startup script---we don't want to wait for it since that requires an active connection to the control plane.
2025-05-01 14:25:02 +04:00
Spike Curtis 35d686caef chore: add Spike & Cian as CODEOWNERS for provisionerd proto (#17629)
Adds @spikecurtis  and @johnstcn as CODEOWNERS of the provisioner protocol files. These need to be versioned, so we need some human review over changes.
2025-05-01 14:24:51 +04:00
Yevhenii Shcherbina 98e5611e16 fix: fix for prebuilds claiming and deletion (#17624)
PR contains:
- fix for claiming & deleting prebuilds with immutable params
- unit test for claiming scenario
- unit test for deletion scenario

The parameter resolver was failing when deleting/claiming prebuilds
because a value for a previously-used parameter was provided to the
resolver, but since the value was unchanged (it's coming from the
preset) it failed in the resolver. The resolver was missing a check to
see if the old value != new value; if the values match then there's no
mutation of an immutable parameter.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-05-01 08:52:23 +00:00
Ethan c7fc7b91ec fix: create directory before writing coder connect network info file (#17628)
The regular network info file creation code also calls `Mkdirall`.

Wasn't picked up in manual testing as I already had the `/net` folder in
my VSCode.

Wasn't picked up in automated testing because we use an in-memory FS,
which for some reason does this implicitly.
2025-05-01 16:53:13 +10:00
Jaayden Halko 4de7661c0b fix: remove unused import (#17626) 2025-04-30 18:09:00 -04:00
Jaayden Halko d104cd636d fix: display validation error for workspace name (#17564)
- Display form validation error for workspace name
- Scroll to the workspace name field if there is a validation error
2025-04-30 16:45:54 -04:00
dependabot[bot] 6bafe35774 chore: bump vite from 5.4.18 to 5.4.19 in /site (#17625)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite)
from 5.4.18 to 5.4.19.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v5.4.19</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v5.4.19/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/v5.4.19/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted -->5.4.19 (2025-04-30)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19965">#19965</a>,
check static serve file inside sirv (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19966">#19966</a>)
(<a
href="https://github.com/vitejs/vite/commit/766947e7cbf1cdd07df9737394e8c870401b78b0">766947e</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19965">#19965</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/19966">#19966</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/80a333a23103ced0442d4463d1191433d90f5e19"><code>80a333a</code></a>
release: v5.4.19</li>
<li><a
href="https://github.com/vitejs/vite/commit/766947e7cbf1cdd07df9737394e8c870401b78b0"><code>766947e</code></a>
fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19965">#19965</a>,
check static serve file inside sirv (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19966">#19966</a>)</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite/commits/v5.4.19/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vite&package-manager=npm_and_yarn&previous-version=5.4.18&new-version=5.4.19)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-30 19:17:56 +00:00
brettkolodny f108f9d71f chore: setup knip and remove unused exports, files, and dependencies (#17608)
Closes [coder/interal#600](https://github.com/coder/internal/issues/600)
2025-04-30 15:08:25 -04:00
Bruno Quaresma 205076e6e7 refactor: change how timings are formatted (#17623) 2025-04-30 13:58:12 -03:00
Edward Angert ef101ae2a0 docs: update ai feature stage to beta and ease the intro note's tone (#17620)
[preview](https://coder.com/docs/@ai-feature-stage/ai-coder)
2025-04-30 15:20:44 +00:00
Danny Kopping 6936a7b5a2 fix: fix prebuild omissions (#17579)
Fixes accidental omission from https://github.com/coder/coder/pull/17527

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-04-30 14:26:30 +00:00
Bruno Quaresma ff54ae3f66 fix: update devcontainer data every 10s (#17619)
Fix https://github.com/coder/internal/issues/594

**Notice:**
This is a temporary solution to get the devcontainers feature released.
Maybe a better solution, to avoid pulling the API every 10 seconds, is
to implement a websocket connection to get updates on containers.
2025-04-30 11:17:41 -03:00
Mathias Fredriksson fe4c4122c9 fix(dogfood/coder): increase in-container docker daemon shutdown timeout (#17617)
The default is 10 seconds and will not successfully clean up large
devcontainers inside the workspace.

Follow-up to #17528
2025-04-30 17:01:22 +03:00
M Atif Ali 650a48c210 chore: update windsurf icon (#17607) 2025-04-30 14:00:10 +05:00
Cian Johnston d7e6eb7914 chore(cli): fix test flake when running in coder workspace (#17604)
This test was failing inside a Coder workspace due to
`CODER_AGENT_TOKEN` being set.
2025-04-30 09:18:58 +01:00
Ethan 7a1e56b707 test: avoid sharing echo.Responses across tests (#17610)
I missed this in https://github.com/coder/coder/pull/17211 because I
only searched for `:= &echo.Responses` and not `= &echo.Responses` 🤦

Fixes flakes like
https://github.com/coder/coder/actions/runs/14746732612/job/41395403979
2025-04-30 05:18:13 +00:00
Ethan 53ba3613b3 feat(cli): use coder connect in coder ssh --stdio, if available (#17572)
Closes https://github.com/coder/vscode-coder/issues/447
Closes https://github.com/coder/jetbrains-coder/issues/543
Closes https://github.com/coder/coder-jetbrains-toolbox/issues/21

This PR adds Coder Connect support to `coder ssh --stdio`. 

When connecting to a workspace, if `--force-new-tunnel` is not passed, the CLI will first do a DNS lookup for `<agent>.<workspace>.<owner>.<hostname-suffix>`. If an IP address is returned, and it's within the Coder service prefix, the CLI will not create a new tailnet connection to the workspace, and instead dial the SSH server running on port 22 on the workspace directly over TCP.

This allows IDE extensions to use the Coder Connect tunnel, without requiring any modifications to the extensions themselves. 

Additionally, `using_coder_connect` is added to the `sshNetworkStats` file, which the VS Code extension (and maybe Jetbrains?) will be able to read, and indicate to the user that they are using Coder Connect.

One advantage of this approach is that running `coder ssh --stdio` on an offline workspace with Coder Connect enabled will have the CLI wait for the workspace to build, the agent to connect (and optionally, for the startup scripts to finish), before finally connecting using the Coder Connect tunnel.

As a result, `coder ssh --stdio` has the overhead of looking up the workspace and agent, and checking if they are running. On my device, this meant `coder ssh --stdio <workspace>` was approximately a second slower than just connecting to the workspace directly using `ssh <workspace>.coder` (I would assume anyone serious about their Coder Connect usage would know to just do the latter anyway).
 
To ensure this doesn't come at a significant performance cost, I've also benchmarked this PR.

<details>
<summary>Benchmark</summary>

## Methodology
All tests were completed on `dev.coder.com`, where a Linux workspace running in AWS `us-west1` was created.
The machine running Coder Desktop (the 'client') was a Windows VM running in the same AWS region and VPC as the workspace.

To test the performance of specifically the SSH connection, a port was forwarded between the client and workspace using:
```
ssh -p 22 -L7001:localhost:7001 <host>
```
where `host` was either an alias for an SSH ProxyCommand that called `coder ssh`, or a Coder Connect hostname.

For latency, [`tcping`](https://www.elifulkerson.com/projects/tcping.php) was used against the forwarded port:
```
tcping -n 100 localhost 7001
```

For throughput, [`iperf3`](https://iperf.fr/iperf-download.php) was used:
```
iperf3 -c localhost -p 7001
```
where an `iperf3` server was running on the workspace on port 7001.

## Test Cases

### Testcase 1: `coder ssh` `ProxyCommand` that bicopies from Coder Connect
This case tests the implementation in this PR, such that we can write a config like:
```
Host codercliconnect
    ProxyCommand /path/to/coder ssh --stdio workspace
```
With Coder Connect enabled, `ssh -p 22 -L7001:localhost:7001 codercliconnect` will use the Coder Connect tunnel. The results were as follows:

**Throughput, 10 tests, back to back:**
- Average throughput across all tests: 788.20 Mbits/sec
- Minimum average throughput: 731 Mbits/sec
- Maximum average throughput: 871 Mbits/sec
- Standard Deviation: 38.88 Mbits/sec

**Latency, 100 RTTs:**
- Average: 0.369ms
- Minimum: 0.290ms
- Maximum: 0.473ms

### Testcase 2: `ssh` dialing Coder Connect directly without a `ProxyCommand`

This is what we assume to be the 'best' way to use Coder Connect

**Throughput, 10 tests, back to back:**
- Average throughput across all tests: 789.50 Mbits/sec
- Minimum average throughput: 708 Mbits/sec
- Maximum average throughput: 839 Mbits/sec
- Standard Deviation: 39.98 Mbits/sec

**Latency, 100 RTTs:**
- Average: 0.369ms
- Minimum: 0.267ms
- Maximum: 0.440ms

### Testcase 3:  `coder ssh` `ProxyCommand` that creates its own Tailnet connection in-process

This is what normally happens when you run `coder ssh`:

**Throughput, 10 tests, back to back:**
- Average throughput across all tests: 610.20 Mbits/sec
- Minimum average throughput: 569 Mbits/sec
- Maximum average throughput: 664 Mbits/sec
- Standard Deviation: 27.29 Mbits/sec

**Latency, 100 RTTs:**
- Average: 0.335ms
- Minimum: 0.262ms
- Maximum: 0.452ms

## Analysis

Performing a two-tailed, unpaired t-test against the throughput of testcases 1 and 2, we find a P value of `0.9450`. This suggests the difference between the data sets is not statistically significant. In other words, there is a 94.5% chance that the difference between the data sets is due to chance.

## Conclusion

From the t-test, and by comparison to the status quo (regular `coder ssh`, which uses gvisor, and is noticeably slower), I think it's safe to say any impact on throughput or latency by the `ProxyCommand` performing a bicopy against Coder Connect is negligible. Users are very much unlikely to run into performance issues as a result of using Coder Connect via `coder ssh`, as implemented in this PR.

Less scientifically, I ran these same tests on my home network with my Sydney workspace, and both throughput and latency were consistent across testcases 1 and 2.

</details>
2025-04-30 15:17:10 +10:00
ケイラ 70ea6788db chore: make the template docs view the default (#17606) 2025-04-29 16:12:39 -06:00
Stephen Kirby 67e1ab407c chore(docs): update release calendar for 2.21 patches (#17605) 2025-04-29 15:34:00 +00:00
Cian Johnston 2acf0adcf2 chore(codersdk/toolsdk): improve static analyzability of toolsdk.Tools (#17562)
* Refactors toolsdk.Tools to remove opaque `map[string]any` argument in
favour of typed args structs.
* Refactors toolsdk.Tools to remove opaque passing of dependencies via
`context.Context` in favour of a tool dependencies struct.
* Adds panic recovery and clean context middleware to all tools.
* Adds `GenericTool` implementation to allow keeping `toolsdk.All` with
uniform type signature while maintaining type information in handlers.
* Adds stricter checks to `patchWorkspaceAgentAppStatus` handler.
2025-04-29 16:05:23 +01:00
Mathias Fredriksson 1fc74f629e refactor(agent): update agentcontainers api initialization (#17600)
There were too many ways to configure the agentcontainers API resulting
in inconsistent behavior or features not being enabled. This refactor
introduces a control flag for enabling or disabling the containers API.
When disabled, all implementations are no-op and explicit endpoint
behaviors are defined. When enabled, concrete implementations are used
by default but can be overridden by passing options.
2025-04-29 17:53:10 +03:00
Cian Johnston 22b932a8e0 fix(cli): fix prompt issue in mcp configure claude-code (#17599)
* Updates default Coder prompt.
* Skips the directions to report tasks if the pre-requisites are not
available (agent token and app slug).
* Adds the capability to override the default Coder prompt via
`CODER_MCP_CLAUDE_CODER_PROMPT`.
2025-04-29 15:23:16 +01:00
Yevhenii Shcherbina 02b2de9ae4 refactor: skip reconciliation for some presets (#17595) 2025-04-29 07:55:37 -04:00
Mathias Fredriksson 268a50c193 feat(agent/agentcontainers): add file watcher and dirty status (#17573)
Fixes coder/internal#479
Fixes coder/internal#480
2025-04-29 11:53:58 +03:00
brettkolodny b6146dfe8a chore: remove circular dependencies (#17585)
I've been bit in the past by hard to deduce bugs caused by circular
dependencies within TS projects. On a hunch that this could be
contributing to some flaky tests I've used the tool
[dpdm](https://github.com/acrazing/dpdm) to find and remove them.

This PR does the following:
- Move around exports/create new files to remove any non-type circular
depencies
- Add dpdm as a dev dependency and create the `check:circular-depency`
pnpm script
2025-04-28 16:51:58 -04:00
ケイラ 12589026b6 chore: update error message for duplicate organization members (#17594)
Closes https://github.com/coder/internal/issues/345
2025-04-28 14:51:33 -06:00
Yevhenii Shcherbina a78f0fc4e1 refactor: use specific error for agpl and prebuilds (#17591)
Follow-up PR to https://github.com/coder/coder/pull/17458
Addresses this discussion:
https://github.com/coder/coder/pull/17458#discussion_r2055940797
2025-04-28 16:37:41 -04:00
Bruno Quaresma 1da27a1ebc fix: handle missed actions in workspace timings (#17593)
Fix https://github.com/coder/coder/issues/16409

Since the provisioner timings action is not strongly typed, but it is
typed as a generic string, and we are not using
`noUncheckedIndexedAccess`, we can miss some of the actions returned
from the API, causing type errors. To avoid that, I changed the code to
be extra safe by adding `undefined` into the return type.
2025-04-28 15:20:07 -03:00
Bruno Quaresma df47c300f3 fix: fix script timings spam in the workspace UI (#17590)
Fix https://github.com/coder/coder/issues/17188

We forgot to filter the scripts by `run_on_start`, since we only
calculate timings in the start phase, which was causing the miss match
between the expected script timings count, and the loop in the refetch
logic.

While I think this fix is enough for now, I think the server should be
responsible to telling the client when to stop fetching. It could be a
simple attribute such as `done: false | true` or a websocket endpoint as
suggested by @dannykopping
[here](https://github.com/coder/coder/issues/17188#issuecomment-2788235333).
2025-04-28 14:22:43 -03:00
Steven Masley 14105ff301 test: do not run memory race test in parallel (#17582)
Closes
https://github.com/coder/internal/issues/597#issuecomment-2835262922

The parallelized tests share configs, which when accessed concurrently
throw race errors. The configs are read only, so it is fine to run these
tests with shared idp configs.
2025-04-28 12:20:07 -05:00
Steven Masley b9177eff7f chore: update guts to latest, using mutations to prevent diffs (#17588)
Guts changes: https://github.com/coder/guts/compare/v1.1.0...main
2025-04-28 12:19:41 -05:00
Steven Masley 37c5e7c440 chore: return safe copy of string slice in 'ParseStringSliceClaim' (#17439)
Claims parsed should be safe to mutate and filter. This was likely not
causing any bugs or issues, and just doing this out of precaution
2025-04-28 12:18:02 -05:00
Yevhenii Shcherbina 9167cbfe4c refactor: claim prebuilt workspace tests (#17567)
Follow-up to: https://github.com/coder/coder/pull/17458
Specifically it addresses these discussions:
- https://github.com/coder/coder/pull/17458#discussion_r2053531445
2025-04-28 12:49:23 -04:00
Bruno Quaresma 3ab3ef865c feat: add link to provisioner jobs and daemons (#17509)
Close https://github.com/coder/coder/issues/17314

**Demo**


https://github.com/user-attachments/assets/db37aa67-4755-4b72-a54d-2c3f0c297b7d

**Changes**
- Added the `xs` button variant
- Display all the daemons - idle and offline - and set a size limit to
100 results (explanation in the demo)
- Filter daemons and jobs by ID
2025-04-28 11:38:32 -03:00
Bruno Quaresma 5ca90aeb59 fix: handle null value for experiments (#17584)
Fix https://github.com/coder/coder/issues/17583

**Relevant info**
- `option.value` can be `null`
- It is always better to use `unknown` instead of `any`, and use type
assertion functions as `Array.isArray()` before using/accessing object
properties and functions
2025-04-28 11:12:49 -03:00
dependabot[bot] 0a26eeec0c ci: bump the github-actions group with 7 updates (#17581)
Bumps the github-actions group with 7 updates:

| Package | From | To |
| --- | --- | --- |
|
[step-security/harden-runner](https://github.com/step-security/harden-runner)
| `2.11.1` | `2.12.0` |
|
[google-github-actions/auth](https://github.com/google-github-actions/auth)
| `2.1.8` | `2.1.10` |
|
[actions/download-artifact](https://github.com/actions/download-artifact)
| `4.2.1` | `4.3.0` |
| [actions/attest](https://github.com/actions/attest) | `2.2.1` |
`2.3.0` |
|
[tj-actions/changed-files](https://github.com/tj-actions/changed-files)
| `9934ab3fdf63239da75d9e0fbd339c48620c72c4` |
`5426ecc3f5c2b10effaefbd374f0abdc6a571b2f` |
|
[nix-community/cache-nix-action](https://github.com/nix-community/cache-nix-action)
| `6.1.2` | `6.1.3` |
| [github/codeql-action](https://github.com/github/codeql-action) |
`3.28.15` | `3.28.16` |

Updates `step-security/harden-runner` from 2.11.1 to 2.12.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/step-security/harden-runner/releases">step-security/harden-runner's
releases</a>.</em></p>
<blockquote>
<h2>v2.12.0</h2>
<h2>What's Changed</h2>
<ol>
<li>
<p>A new option, <code>disable-sudo-and-containers</code>, is now
available to replace the <code>disable-sudo policy</code>, addressing
Docker-based privilege escalation (<a
href="https://github.com/step-security/harden-runner/security/advisories/GHSA-mxr3-8whj-j74r">CVE-2025-32955</a>).
More details can be found in this <a
href="https://www.stepsecurity.io/blog/evolving-harden-runners-disable-sudo-policy-for-improved-runner-security">blog
post</a>.</p>
</li>
<li>
<p>New detections have been added based on insights from the tj-actions
and reviewdog actions incidents.</p>
</li>
</ol>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/step-security/harden-runner/compare/v2...v2.12.0">https://github.com/step-security/harden-runner/compare/v2...v2.12.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/step-security/harden-runner/commit/0634a2670c59f64b4a01f0f96f84700a4088b9f0"><code>0634a26</code></a>
Merge pull request <a
href="https://redirect.github.com/step-security/harden-runner/issues/541">#541</a>
from step-security/rc-20</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/2e3c5113419044c10e6826351ff7cf7d56cbebe4"><code>2e3c511</code></a>
Update action.yml</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/40873e6a41e9ae4f46268f8ee038b3561bb88504"><code>40873e6</code></a>
Update README.md</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/484c2799ec63f20b4acc41bcf649dd4003718616"><code>484c279</code></a>
Update README.md</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/4c8582f45544ce2dafb2cfae82cfbebf0f41bde2"><code>4c8582f</code></a>
Update agent versions</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/e8d595cd66544d43aca8ac7e42a212a5a83b41f8"><code>e8d595c</code></a>
fix disable_sudo_and_containers bug</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/5d277fc8734baba8746d0c18cb0a2594d4692c66"><code>5d277fc</code></a>
fix journalctl related bug</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/ff2ab228bdb9f0c9129169d47dbb2bdf4b8f9b0e"><code>ff2ab22</code></a>
Merge pull request <a
href="https://redirect.github.com/step-security/harden-runner/issues/536">#536</a>
from rohan-stepsecurity/feat/flag/disable-sudo-and-co...</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/b81d650d0e627a80d0d73d192b33d729507e0ef5"><code>b81d650</code></a>
fix: run sudo command only when both disable-sudo and
disable-sudo-and-docker...</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/769df4ef5d6336b33b11e5b0d43934309cf439f6"><code>769df4e</code></a>
Update agent</li>
<li>Additional commits viewable in <a
href="https://github.com/step-security/harden-runner/compare/c6295a65d1254861815972266d5933fd6e532bdf...0634a2670c59f64b4a01f0f96f84700a4088b9f0">compare
view</a></li>
</ul>
</details>
<br />

Updates `google-github-actions/auth` from 2.1.8 to 2.1.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/google-github-actions/auth/releases">google-github-actions/auth's
releases</a>.</em></p>
<blockquote>
<h2>v2.1.10</h2>
<h2>What's Changed</h2>
<ul>
<li>Declare workflow permissions by <a
href="https://github.com/sethvargo"><code>@​sethvargo</code></a> in <a
href="https://redirect.github.com/google-github-actions/auth/pull/482">google-github-actions/auth#482</a></li>
<li>Document that the OIDC token expires in 5min by <a
href="https://github.com/sethvargo"><code>@​sethvargo</code></a> in <a
href="https://redirect.github.com/google-github-actions/auth/pull/483">google-github-actions/auth#483</a></li>
<li>Release: v2.1.10 by <a
href="https://github.com/google-github-actions-bot"><code>@​google-github-actions-bot</code></a>
in <a
href="https://redirect.github.com/google-github-actions/auth/pull/484">google-github-actions/auth#484</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/google-github-actions/auth/compare/v2.1.9...v2.1.10">https://github.com/google-github-actions/auth/compare/v2.1.9...v2.1.10</a></p>
<h2>v2.1.9</h2>
<h2>What's Changed</h2>
<ul>
<li>Use our custom boolean parsing by <a
href="https://github.com/sethvargo"><code>@​sethvargo</code></a> in <a
href="https://redirect.github.com/google-github-actions/auth/pull/478">google-github-actions/auth#478</a></li>
<li>Update deps by <a
href="https://github.com/sethvargo"><code>@​sethvargo</code></a> in <a
href="https://redirect.github.com/google-github-actions/auth/pull/479">google-github-actions/auth#479</a></li>
<li>Release: v2.1.9 by <a
href="https://github.com/google-github-actions-bot"><code>@​google-github-actions-bot</code></a>
in <a
href="https://redirect.github.com/google-github-actions/auth/pull/480">google-github-actions/auth#480</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/google-github-actions/auth/compare/v2.1.8...v2.1.9">https://github.com/google-github-actions/auth/compare/v2.1.8...v2.1.9</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/google-github-actions/auth/commit/ba79af03959ebeac9769e648f473a284504d9193"><code>ba79af0</code></a>
Release: v2.1.10 (<a
href="https://redirect.github.com/google-github-actions/auth/issues/484">#484</a>)</li>
<li><a
href="https://github.com/google-github-actions/auth/commit/bfaa66bd663615688155de119a676d67396f6bb7"><code>bfaa66b</code></a>
Document that the OIDC token expires in 5min (<a
href="https://redirect.github.com/google-github-actions/auth/issues/483">#483</a>)</li>
<li><a
href="https://github.com/google-github-actions/auth/commit/d0822ad9bf77d35dee590e455d9ef5b96ccb243c"><code>d0822ad</code></a>
Declare workflow permissions (<a
href="https://redirect.github.com/google-github-actions/auth/issues/482">#482</a>)</li>
<li><a
href="https://github.com/google-github-actions/auth/commit/7b53cdc2a387814ed14eec026287aac689ae8c9b"><code>7b53cdc</code></a>
Release: v2.1.9 (<a
href="https://redirect.github.com/google-github-actions/auth/issues/480">#480</a>)</li>
<li><a
href="https://github.com/google-github-actions/auth/commit/a9cfddf5d2f27aa426027a399f75d209953ade8e"><code>a9cfddf</code></a>
Update deps (<a
href="https://redirect.github.com/google-github-actions/auth/issues/479">#479</a>)</li>
<li><a
href="https://github.com/google-github-actions/auth/commit/b011f3988e66cb193db0f34974b1d7cde74e4f95"><code>b011f39</code></a>
Use our custom boolean parsing (<a
href="https://redirect.github.com/google-github-actions/auth/issues/478">#478</a>)</li>
<li>See full diff in <a
href="https://github.com/google-github-actions/auth/compare/71f986410dfbc7added4569d411d040a91dc6935...ba79af03959ebeac9769e648f473a284504d9193">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/download-artifact` from 4.2.1 to 4.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: implement new <code>artifact-ids</code> input by <a
href="https://github.com/GrantBirki"><code>@​GrantBirki</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/401">actions/download-artifact#401</a></li>
<li>Fix workflow example for downloading by artifact ID by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/402">actions/download-artifact#402</a></li>
<li>Prep for v4.3.0 release by <a
href="https://github.com/robherley"><code>@​robherley</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/404">actions/download-artifact#404</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/GrantBirki"><code>@​GrantBirki</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/401">actions/download-artifact#401</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v4.2.1...v4.3.0">https://github.com/actions/download-artifact/compare/v4.2.1...v4.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/download-artifact/commit/d3f86a106a0bac45b974a628896c90dbdf5c8093"><code>d3f86a1</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/404">#404</a>
from actions/robherley/v4.3.0</li>
<li><a
href="https://github.com/actions/download-artifact/commit/fc02353415da80201a0da48ab47022efd7725d11"><code>fc02353</code></a>
prep for v4.3.0 release</li>
<li><a
href="https://github.com/actions/download-artifact/commit/77454371a433f370a16d329ef7db197f700a7a8f"><code>7745437</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/402">#402</a>
from actions/joshmgross/download-by-id-example</li>
<li><a
href="https://github.com/actions/download-artifact/commit/84fc7a0a358aabc7f97f7f590cbfc25f57e26c6a"><code>84fc7a0</code></a>
Remove path filters from Check dist workflow</li>
<li><a
href="https://github.com/actions/download-artifact/commit/67f2bc382f6ba5ba75812a05909e8c25a366b5fb"><code>67f2bc3</code></a>
Fix workflow example for downloading by artifact ID</li>
<li><a
href="https://github.com/actions/download-artifact/commit/8ea3c2c174f79a56792e9fdd9baad75d27c5d369"><code>8ea3c2c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/401">#401</a>
from actions/download-by-id</li>
<li><a
href="https://github.com/actions/download-artifact/commit/d219c630f65d8bd14366a9e2f731cbf854f62258"><code>d219c63</code></a>
add supporting unit tests for artifact downloads with ids</li>
<li><a
href="https://github.com/actions/download-artifact/commit/54124fbd881f8ce794405a06896c93c49c17463e"><code>54124fb</code></a>
revert <code>getArtifact()</code> changes - for now we have to list and
filter by artifa...</li>
<li><a
href="https://github.com/actions/download-artifact/commit/b83057b90d3e218abf5c7b1906579eb6c598ae85"><code>b83057b</code></a>
bundle</li>
<li><a
href="https://github.com/actions/download-artifact/commit/171183c7dce98c3cf8a1fc842429d0a38ed21d33"><code>171183c</code></a>
use the same <code>artifactClient.getArtifact</code> structure as seen
above in `isSingl...</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/download-artifact/compare/95815c38cf2ff2164869cbab79da8d1f422bc89e...d3f86a106a0bac45b974a628896c90dbdf5c8093">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/attest` from 2.2.1 to 2.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/attest/releases">actions/attest's
releases</a>.</em></p>
<blockquote>
<h2>v2.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​octokit/request</code> from 8.2.0 to 8.4.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/attest/pull/229">actions/attest#229</a></li>
<li>Bump <code>@​sigstore/oci</code> from 0.4.0 to 0.5.0 by <a
href="https://github.com/bdehamer"><code>@​bdehamer</code></a> in <a
href="https://redirect.github.com/actions/attest/pull/235">actions/attest#235</a>
<ul>
<li>Adds support for reading the <code>HttpHeaders</code> value from the
Docker config file</li>
</ul>
</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/attest/compare/v2...v2.3.0">https://github.com/actions/attest/compare/v2...v2.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/attest/commit/afd638254319277bb3d7f0a234478733e2e46a73"><code>afd6382</code></a>
Bump <code>@​sigstore/oci</code> from 0.4.0 to 0.5.0 (<a
href="https://redirect.github.com/actions/attest/issues/235">#235</a>)</li>
<li><a
href="https://github.com/actions/attest/commit/d73111199c05526c91684e5e845606249f88accc"><code>d731111</code></a>
Bump the npm-development group across 1 directory with 6 updates (<a
href="https://redirect.github.com/actions/attest/issues/234">#234</a>)</li>
<li><a
href="https://github.com/actions/attest/commit/13aa4f6a9ce09dcf318f1ac18a48388699d96a62"><code>13aa4f6</code></a>
Bump <code>@​octokit/request</code> from 8.2.0 to 8.4.1 (<a
href="https://redirect.github.com/actions/attest/issues/229">#229</a>)</li>
<li><a
href="https://github.com/actions/attest/commit/129b656e44fad75bb154cc2953cf07ba1da8a419"><code>129b656</code></a>
Bump the npm-development group with 3 updates (<a
href="https://redirect.github.com/actions/attest/issues/227">#227</a>)</li>
<li><a
href="https://github.com/actions/attest/commit/f3c169c8df83481993e3075060fc687e87747125"><code>f3c169c</code></a>
Bump the npm-development group with 5 updates (<a
href="https://redirect.github.com/actions/attest/issues/225">#225</a>)</li>
<li><a
href="https://github.com/actions/attest/commit/48e991bfda5b806f66f0a2ad8ae4e17f14cdfd33"><code>48e991b</code></a>
Bump the npm-development group across 1 directory with 6 updates (<a
href="https://redirect.github.com/actions/attest/issues/223">#223</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/attest/compare/a63cfcc7d1aab266ee064c58250cfc2c7d07bc31...afd638254319277bb3d7f0a234478733e2e46a73">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/changed-files` from
9934ab3fdf63239da75d9e0fbd339c48620c72c4 to
5426ecc3f5c2b10effaefbd374f0abdc6a571b2f
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/changed-files/blob/main/HISTORY.md">tj-actions/changed-files's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.4...v46.0.5">46.0.5</a>
- (2025-04-09)</h1>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li><strong>deps:</strong> Bump yaml from 2.7.0 to 2.7.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2520">#2520</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/ed68ef82c095e0d48ec87eccea555d944a631a4c">ed68ef8</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump typescript from 5.8.2 to 5.8.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2516">#2516</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/a7bc14b808f23d3b467a4079c69a81f1a4500fd5">a7bc14b</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump <code>@​types/node</code> from
22.13.11 to 22.14.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2517">#2517</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/3d751f6b6d84071a17e1b9cf4ed79a80a27dd0ab">3d751f6</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump eslint-plugin-prettier from 5.2.3 to
5.2.6 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2519">#2519</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/e2fda4ec3cb0bc2a353843cae823430b3124db8f">e2fda4e</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump ts-jest from 29.2.6 to 29.3.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2518">#2518</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/0bed1b1132ec4879a39a2d624cf82a00d0bcfa48">0bed1b1</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump github/codeql-action from 3.28.12 to
3.28.15 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2530">#2530</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/68024587dc36f49685c96d59d3f1081830f968bb">6802458</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/branch-names from 8.0.1 to
8.1.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2521">#2521</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/cf2e39e86bf842d1f9bc5bca56c0a6b207cca792">cf2e39e</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/verify-changed-files from
20.0.1 to 20.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2523">#2523</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6abeaa506a419f85fa9e681260b443adbeebb3d4">6abeaa5</a>)
- (dependabot[bot])</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2511">#2511</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/6f67ee9ac810f0192ea7b3d2086406f97847bcf9">6f67ee9</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.3...v46.0.4">46.0.4</a>
- (2025-04-03)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li>Bug modified_keys and changed_key outputs not set when no changes
detected (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2509">#2509</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6cb76d07bee4c9772c6882c06c37837bf82a04d3">6cb76d0</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<ul>
<li>Update readme (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2508">#2508</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/b74df86ccb65173a8e33ba5492ac1a2ca6b216fd">b74df86</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2506">#2506</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted -->
Co-authored-by: Tonye Jack <a
href="mailto:jtonye@ymail.com">jtonye@ymail.com</a> (<a
href="https://github.com/tj-actions/changed-files/commit/27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99">27ae6b3</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.2...v46.0.3">46.0.3</a>
- (2025-03-23)</h1>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2501">#2501</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/41e0de576a0f2b64d9f06f2773f539109e55a70a">41e0de5</a>)
- (github-actions[bot])</p>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2499">#2499</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/945787811a795cd840a1157ac590dd7827a05c8e">9457878</a>)
- (github-actions[bot])</p>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/changed-files/commit/5426ecc3f5c2b10effaefbd374f0abdc6a571b2f"><code>5426ecc</code></a>
chore(deps): bump actions/download-artifact from 4.2.1 to 4.3.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2545">#2545</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/513a44e6095ccea82c33927169db11eb75f72791"><code>513a44e</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.14.1 to 22.15.0
(<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2544">#2544</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/46e217dc3e3b2601594036314ca9212588075592"><code>46e217d</code></a>
chore(deps): bump github/codeql-action from 3.28.15 to 3.28.16 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2542">#2542</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/c34c1c13a740b06851baff92ab9a653d93ad6ce7"><code>c34c1c1</code></a>
chore(deps): bump actions/setup-node from 4.3.0 to 4.4.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2539">#2539</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/52c3beb9971d42006b24e86bf3ea3fff18dde67f"><code>52c3beb</code></a>
chore(deps-dev): bump ts-jest from 29.3.1 to 29.3.2 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2536">#2536</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/ea3010bc88ae93076e154efd9eb64d1f5e6993f9"><code>ea3010b</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.14.0 to 22.14.1
(<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2537">#2537</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/be393a90381e27c9fec2c8c2e02b00f005710145"><code>be393a9</code></a>
remove: commit and push step from build job (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2538">#2538</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/9b4bb2bedb217d3ede225b6b07ebde713177cd8f"><code>9b4bb2b</code></a>
chore(deps): bump tj-actions/branch-names from 8.1.0 to 8.2.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2535">#2535</a>)</li>
<li>See full diff in <a
href="https://github.com/tj-actions/changed-files/compare/9934ab3fdf63239da75d9e0fbd339c48620c72c4...5426ecc3f5c2b10effaefbd374f0abdc6a571b2f">compare
view</a></li>
</ul>
</details>
<br />

Updates `nix-community/cache-nix-action` from 6.1.2 to 6.1.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nix-community/cache-nix-action/releases">nix-community/cache-nix-action's
releases</a>.</em></p>
<blockquote>
<h2>v6.1.3</h2>
<h2>Fixes</h2>
<ul>
<li>Use <code>bigint</code> instead of <code>number</code> for the store
size (<a
href="https://redirect.github.com/nix-community/cache-nix-action/issues/117">#117</a>)</li>
<li>Fix saving a cache (<a
href="https://redirect.github.com/nix-community/cache-nix-action/issues/122">#122</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/135667ec418502fa5a3598af6fb9eb733888ce6a"><code>135667e</code></a>
Merge pull request <a
href="https://redirect.github.com/nix-community/cache-nix-action/issues/122">#122</a>
from nix-community/118-bug-cant-save-a-cache</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/e29de90a039b410e88cd97a0029c3cbdad611ad5"><code>e29de90</code></a>
chore: build the action</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/6bd39b8caa31871d2bc38356ab8b94621ca1e116"><code>6bd39b8</code></a>
fix(action): use TarCommandModifiers</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/1b6f6754d3c59414aad4ab660cd611b1e35c0232"><code>1b6f675</code></a>
chore(deps): update buildjet/toolkit</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/2b45b8cabe18b0f3db2eb2cf4e195238eee4a325"><code>2b45b8c</code></a>
chore(deps): update actions/toolkit</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/f68581e27a06c8c9115dec37e42325d562d9664b"><code>f68581e</code></a>
chore: build the action</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/b6406dc6e7f9c6ad6b399ed561f29f7e406544d5"><code>b6406dc</code></a>
Merge pull request <a
href="https://redirect.github.com/nix-community/cache-nix-action/issues/117">#117</a>
from nix-community/116-bug-inputsgcmaxstoresizevalue-...</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/a91821953137cbb5f2a2d45fa174d69fea427ef4"><code>a918219</code></a>
chore: build the action</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/c6081efc5157c972934491630ade96e53259023c"><code>c6081ef</code></a>
feat(ci): add example of large gc-max-store-size</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/cf6af9e3e9fb402a3b92286b7c8b48afa94de5a6"><code>cf6af9e</code></a>
fix(action): use bigint for the store size</li>
<li>Additional commits viewable in <a
href="https://github.com/nix-community/cache-nix-action/compare/c448f065ba14308da81de769632ca67a3ce67cf5...135667ec418502fa5a3598af6fb9eb733888ce6a">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action` from 3.28.15 to 3.28.16
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.28.16</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.16 - 23 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.1. <a
href="https://redirect.github.com/github/codeql-action/pull/2863">#2863</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.16/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.28.16 - 23 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.1. <a
href="https://redirect.github.com/github/codeql-action/pull/2863">#2863</a></li>
</ul>
<h2>3.28.15 - 07 Apr 2025</h2>
<ul>
<li>Fix bug where the action would fail if it tried to produce a debug
artifact with more than 65535 files. <a
href="https://redirect.github.com/github/codeql-action/pull/2842">#2842</a></li>
</ul>
<h2>3.28.14 - 07 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.0. <a
href="https://redirect.github.com/github/codeql-action/pull/2838">#2838</a></li>
</ul>
<h2>3.28.13 - 24 Mar 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.12 - 19 Mar 2025</h2>
<ul>
<li>Dependency caching should now cache more dependencies for Java
<code>build-mode: none</code> extractions. This should speed up
workflows and avoid inconsistent alerts in some cases.</li>
<li>Update default CodeQL bundle version to 2.20.7. <a
href="https://redirect.github.com/github/codeql-action/pull/2810">#2810</a></li>
</ul>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<h2>3.28.10 - 21 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.5. <a
href="https://redirect.github.com/github/codeql-action/pull/2772">#2772</a></li>
<li>Address an issue where the CodeQL Bundle would occasionally fail to
decompress on macOS. <a
href="https://redirect.github.com/github/codeql-action/pull/2768">#2768</a></li>
</ul>
<h2>3.28.9 - 07 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.4. <a
href="https://redirect.github.com/github/codeql-action/pull/2753">#2753</a></li>
</ul>
<h2>3.28.8 - 29 Jan 2025</h2>
<ul>
<li>Enable support for Kotlin 2.1.10 when running with CodeQL CLI
v2.20.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2744">#2744</a></li>
</ul>
<h2>3.28.7 - 29 Jan 2025</h2>
<p>No user facing changes.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/28deaeda66b76a05916b6923827895f2b14ab387"><code>28deaed</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2865">#2865</a>
from github/update-v3.28.16-2a8cbadc0</li>
<li><a
href="https://github.com/github/codeql-action/commit/03c5d71c11f6cb2c5ba7eef371219a862be30193"><code>03c5d71</code></a>
Update changelog for v3.28.16</li>
<li><a
href="https://github.com/github/codeql-action/commit/2a8cbadc02bb64a7fd15d37c977acbad02496c80"><code>2a8cbad</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2863">#2863</a>
from github/update-bundle/codeql-bundle-v2.21.1</li>
<li><a
href="https://github.com/github/codeql-action/commit/f76eaf51a636a5c1d927998267d92d6475363ace"><code>f76eaf5</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/e63b3f5166c15fda4eb17886f01abe9445dd13f5"><code>e63b3f5</code></a>
Update default bundle to codeql-bundle-v2.21.1</li>
<li><a
href="https://github.com/github/codeql-action/commit/4c3e5362829f0b0bb62ff5f6c938d7f95574c306"><code>4c3e536</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2853">#2853</a>
from github/dependabot/npm_and_yarn/npm-7d84c66b66</li>
<li><a
href="https://github.com/github/codeql-action/commit/56dd02f26d99811d607284494ff84b7d862fe837"><code>56dd02f</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2852">#2852</a>
from github/dependabot/github_actions/actions-457587...</li>
<li><a
href="https://github.com/github/codeql-action/commit/192406dd845fb2228fcea74898b98df2a6cdcef6"><code>192406d</code></a>
Merge branch 'main' into
dependabot/github_actions/actions-4575878e06</li>
<li><a
href="https://github.com/github/codeql-action/commit/c7dbb2084ed1bb623fbbb3976cd6dbae6daaf1fe"><code>c7dbb20</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2857">#2857</a>
from github/nickfyson/address-vulns</li>
<li><a
href="https://github.com/github/codeql-action/commit/9a45cd8c5025281c30bbb652197ace083c291e49"><code>9a45cd8</code></a>
move use of input variables into env vars</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/45775bd8235c68ba998cffa5171334d58593da47...28deaeda66b76a05916b6923827895f2b14ab387">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 13:22:26 +00:00
dependabot[bot] b299ebebf7 chore: bump github.com/valyala/fasthttp from 1.60.0 to 1.61.0 (#17575)
Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp)
from 1.60.0 to 1.61.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/valyala/fasthttp/releases">github.com/valyala/fasthttp's
releases</a>.</em></p>
<blockquote>
<h2>v1.61.0</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(deps): bump golang.org/x/sys from 0.31.0 to 0.32.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1989">valyala/fasthttp#1989</a></li>
<li>chore(deps): bump golang.org/x/crypto from 0.36.0 to 0.37.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1988">valyala/fasthttp#1988</a></li>
<li>chore(deps): bump securego/gosec from 2.22.2 to 2.22.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1990">valyala/fasthttp#1990</a></li>
<li>chore(deps): bump golang.org/x/net from 0.38.0 to 0.39.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1991">valyala/fasthttp#1991</a></li>
<li>Fix round robin addresses in dual stack dialing by <a
href="https://github.com/raviqqe"><code>@​raviqqe</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1995">valyala/fasthttp#1995</a></li>
<li>Fix panic when perIPConn.Close is called multiple times by <a
href="https://github.com/erikdubbelboer"><code>@​erikdubbelboer</code></a>
in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1993">valyala/fasthttp#1993</a></li>
<li>early hint functionality by <a
href="https://github.com/pjebs"><code>@​pjebs</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1996">valyala/fasthttp#1996</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/raviqqe"><code>@​raviqqe</code></a> made
their first contribution in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1995">valyala/fasthttp#1995</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/valyala/fasthttp/compare/v1.60.0...v1.61.0">https://github.com/valyala/fasthttp/compare/v1.60.0...v1.61.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/valyala/fasthttp/commit/a05560dd7e07834473c374ba3d1bfc9dfa508d64"><code>a05560d</code></a>
implement early hints (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1996">#1996</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/48f3a2f423f103cd67e504a51f3ec3a1381a5620"><code>48f3a2f</code></a>
Fix panic when perIPConn.Close is called multiple times (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1993">#1993</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/e380d34bce703d5d43b8effcef66b7305af12a35"><code>e380d34</code></a>
Fix round robin addresses in dual stack dialing (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1995">#1995</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/4c71125994a1a67c8c6cb979142ae4269c5d89f1"><code>4c71125</code></a>
chore(deps): bump golang.org/x/net from 0.38.0 to 0.39.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1991">#1991</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/76acf1443d615f73837ed7ef2de7924316746809"><code>76acf14</code></a>
chore(deps): bump securego/gosec from 2.22.2 to 2.22.3 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1990">#1990</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/236b2f3148d527c23524f44d9b521d7640dd06a6"><code>236b2f3</code></a>
chore(deps): bump golang.org/x/crypto from 0.36.0 to 0.37.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1988">#1988</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/2629d9d8697d11b2085c73f5005a234448336e84"><code>2629d9d</code></a>
chore(deps): bump golang.org/x/sys from 0.31.0 to 0.32.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1989">#1989</a>)</li>
<li>See full diff in <a
href="https://github.com/valyala/fasthttp/compare/v1.60.0...v1.61.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/valyala/fasthttp&package-manager=go_modules&previous-version=1.60.0&new-version=1.61.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 13:12:46 +00:00
dependabot[bot] 38e7793c91 chore: bump github.com/gohugoio/hugo from 0.146.3 to 0.147.0 (#17577)
Bumps [github.com/gohugoio/hugo](https://github.com/gohugoio/hugo) from
0.146.3 to 0.147.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/gohugoio/hugo/releases">github.com/gohugoio/hugo's
releases</a>.</em></p>
<blockquote>
<h2>v0.147.0</h2>
<p>This release comes with a new <code>aligny</code> option (shoutout to
<a href="https://github.com/pranshugaba"><code>@​pranshugaba</code></a>
for the implementation) for <a
href="https://gohugo.io/functions/images/text/">images.Text</a> that, in
combination with <code>alignx</code> makes it simple to e.g. center the
text on top of image in both axis. But the main reason this release
comes now and not later, is the improvements/fixes to the order Hugo
applies the default configuration to some keys. This is inherited from
how we did this before we rewrote the configuration handling, and it
made the merging of configuration from modules/themes into the config
root harder and less flexible than it had to be. Me, <a
href="https://github.com/bep"><code>@​bep</code></a>, looking into this,
was triggered by <a
href="https://discourse.gohugo.io/t/how-to-manage-common-config-in-hugo-using-modules/54485/4">this</a>
forum topic. Having many sites share a common configuration is very
useful. With this release, you can simply get what the thread starter
asks for by doing something à la:</p>
<pre lang="toml"><code>baseURL = &quot;http://example.org&quot;
title = &quot;My Hugo Site&quot;
<h1>... import any themes/modules.</h1>
<h1>This will merge in all config imported from imported modules.</h1>
<p>_merge = &quot;deep&quot;
</code></pre></p>
<p>See the <a
href="https://gohugo.io/configuration/introduction/#merge-configuration-settings">documentation</a>
for details.</p>
<h2>Bug fixes</h2>
<ul>
<li>tpl: Fix it so we always prefer internal codeblock rendering over
render-codeblock-foo.html and similar 07983e04e <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13651">#13651</a></li>
<li>tpl/tplimpl: Fix allowFullScreen option in Vimeo and YouTube
shortcodes 5c491409d <a
href="https://github.com/jmooring"><code>@​jmooring</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13650">#13650</a></li>
<li>config: Fix _merge issue when key doesn't exist on the left side
179aea11a <a href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13643">#13643</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/13646">#13646</a></li>
<li>all: Fix typos 6a0e04241 <a
href="https://github.com/coliff"><code>@​coliff</code></a></li>
</ul>
<h2>Improvements</h2>
<ul>
<li>create/skeletons: Adjust template names in theme skeleton 75b219db8
<a href="https://github.com/jmooring"><code>@​jmooring</code></a></li>
<li>tpl: Remove some unreached code branches ad4f63c92 <a
href="https://github.com/bep"><code>@​bep</code></a></li>
<li>images: Add some test cases for aligny on images.Text 53202314a <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13414">#13414</a></li>
<li>images: Add option for vertical alignment to images.Text 2fce0bac0
<a
href="https://github.com/pranshugaba"><code>@​pranshugaba</code></a></li>
</ul>
<h2>Dependency Updates</h2>
<ul>
<li>build(deps): bump github.com/evanw/esbuild from 0.25.2 to 0.25.3
1bd7ac7ed <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]</li>
<li>build(deps): bump github.com/alecthomas/chroma/v2 from 2.16.0 to
2.17.0 41cb880f9 <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]</li>
</ul>
<h2>v0.146.7</h2>
<h2>Bug fixes</h2>
<ul>
<li>Revert the breaking change from 0.146.0 with dots in content
filenames 496730840 <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13632">#13632</a></li>
<li>tpl: Fix indeterminate template lookup with templates with and
without lang 6d69dc88a <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13636">#13636</a></li>
<li>tpl/collections: Fix where ... not in with empty slice 4eb0e4286 <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13621">#13621</a></li>
<li>tpl: Fix layout fall back logic when layout is set in front matter
but not found 5e62cc6fc <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13630">#13630</a></li>
</ul>
<h2>Improvements</h2>
<ul>
<li>parser/metadecoders: Add CSV targetType (map or slice) option to
transform.Unmarshal db72a1f07 <a
href="https://github.com/jmooring"><code>@​jmooring</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/8859">#8859</a></li>
<li>tpl: Detect and fail on infinite template recursion 1408c156d <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13627">#13627</a></li>
</ul>
<h2>Dependency Updates</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/gohugoio/hugo/commit/7d0039b86ddd6397816cc3383cb0cfa481b15f32"><code>7d0039b</code></a>
releaser: Bump versions for release of 0.147.0</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/07983e04e29986a683c7a9f15d48b83e90aff09c"><code>07983e0</code></a>
tpl: Fix it so we always prefer internal codeblock rendering over
render-code...</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/5c491409d36d31f77cdc0407ed29ae2dca71363b"><code>5c49140</code></a>
tpl/tplimpl: Fix allowFullScreen option in Vimeo and YouTube
shortcodes</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/75b219db896cd0ae962f062b39fd67c38dfc8e5b"><code>75b219d</code></a>
create/skeletons: Adjust template names in theme skeleton</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/ad4f63c92f41824b861d317f9248fb30b7e68076"><code>ad4f63c</code></a>
tpl: Remove some unreached code branches</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/53202314abdd05d8f0b6ffdcef96640ac3267344"><code>5320231</code></a>
images: Add some test cases for aligny on images.Text</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/2fce0bac033d8b7e98046f85f669ba813d862788"><code>2fce0ba</code></a>
images: Add option for vertical alignment to images.Text</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/179aea11ac2ce80a38b211e11fd513cead63b17e"><code>179aea1</code></a>
config: Fix _merge issue when key doesn't exist on the left side</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/61a286595e9a333fef95db1e9a086ef9367b3d87"><code>61a2865</code></a>
Merge commit 'b3d87dd0fd746f07f9afa6e6a2969aea41da6a38'</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/b3d87dd0fd746f07f9afa6e6a2969aea41da6a38"><code>b3d87dd</code></a>
Squashed 'docs/' changes from dc7a9ae12..b654fcba0</li>
<li>Additional commits viewable in <a
href="https://github.com/gohugoio/hugo/compare/v0.146.3...v0.147.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/gohugoio/hugo&package-manager=go_modules&previous-version=0.146.3&new-version=0.147.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 12:22:14 +00:00
dependabot[bot] 42e91de81d chore: bump google.golang.org/api from 0.229.0 to 0.230.0 (#17578)
Bumps
[google.golang.org/api](https://github.com/googleapis/google-api-go-client)
from 0.229.0 to 0.230.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/releases">google.golang.org/api's
releases</a>.</em></p>
<blockquote>
<h2>v0.230.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.229.0...v0.230.0">0.230.0</a>
(2025-04-22)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3111">#3111</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/59f08c8d98394de1311907950ae52b75db151a6a">59f08c8</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3113">#3113</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/40e4fb1ee01719658774befbfc582c20ee06581f">40e4fb1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3114">#3114</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/f0bb0a13159f29b30624027724b3ea0ad08c0ff0">f0bb0a1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3115">#3115</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c122b14b51ab658a5f666b9ec9ab318288c4273d">c122b14</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3117">#3117</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1c0aadbeaf819dfcb52903b978085ac96c12522c">1c0aadb</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3118">#3118</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/2b6fa61936ada3252efc355ea176dd638c2f5baa">2b6fa61</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3120">#3120</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/18c546ede7af9fae3ff7115c01a31208c3a9d734">18c546e</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3121">#3121</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ff1b166e4564423ae96c464cad4435db71cefded">ff1b166</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Removes-redundant (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3095">#3095</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9e9ff112acacecddc17be15d4f37ca45fb9177ad">9e9ff11</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md">google.golang.org/api's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.229.0...v0.230.0">0.230.0</a>
(2025-04-22)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3111">#3111</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/59f08c8d98394de1311907950ae52b75db151a6a">59f08c8</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3113">#3113</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/40e4fb1ee01719658774befbfc582c20ee06581f">40e4fb1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3114">#3114</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/f0bb0a13159f29b30624027724b3ea0ad08c0ff0">f0bb0a1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3115">#3115</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c122b14b51ab658a5f666b9ec9ab318288c4273d">c122b14</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3117">#3117</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1c0aadbeaf819dfcb52903b978085ac96c12522c">1c0aadb</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3118">#3118</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/2b6fa61936ada3252efc355ea176dd638c2f5baa">2b6fa61</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3120">#3120</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/18c546ede7af9fae3ff7115c01a31208c3a9d734">18c546e</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3121">#3121</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ff1b166e4564423ae96c464cad4435db71cefded">ff1b166</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>Removes-redundant (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3095">#3095</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9e9ff112acacecddc17be15d4f37ca45fb9177ad">9e9ff11</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/e4f4ca981adfca5cdf031dd30c645ee356591d12"><code>e4f4ca9</code></a>
chore(main): release 0.230.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3112">#3112</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/ff1b166e4564423ae96c464cad4435db71cefded"><code>ff1b166</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3121">#3121</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/5b0e60da0b3c608ab354297a727eedac9c403fde"><code>5b0e60d</code></a>
chore(all): update all (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3119">#3119</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/18c546ede7af9fae3ff7115c01a31208c3a9d734"><code>18c546e</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3120">#3120</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/2b6fa61936ada3252efc355ea176dd638c2f5baa"><code>2b6fa61</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3118">#3118</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/1c0aadbeaf819dfcb52903b978085ac96c12522c"><code>1c0aadb</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3117">#3117</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/c122b14b51ab658a5f666b9ec9ab318288c4273d"><code>c122b14</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3115">#3115</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/f0bb0a13159f29b30624027724b3ea0ad08c0ff0"><code>f0bb0a1</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3114">#3114</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/9e9ff112acacecddc17be15d4f37ca45fb9177ad"><code>9e9ff11</code></a>
fix: removes-redundant (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3095">#3095</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/40e4fb1ee01719658774befbfc582c20ee06581f"><code>40e4fb1</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3113">#3113</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/googleapis/google-api-go-client/compare/v0.229.0...v0.230.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/api&package-manager=go_modules&previous-version=0.229.0&new-version=0.230.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 12:21:55 +00:00
dependabot[bot] cabfc98030 chore: bump github.com/mark3labs/mcp-go from 0.22.0 to 0.23.1 (#17576)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.22.0 to 0.23.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.23.1</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(client): prevent panics by <a
href="https://github.com/jkoelker"><code>@​jkoelker</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/192">mark3labs/mcp-go#192</a></li>
<li>fix: correct JSON key for client capabilities by <a
href="https://github.com/TBXark"><code>@​TBXark</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/197">mark3labs/mcp-go#197</a></li>
<li>fix(client): check stdio started before sending notification by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/199">mark3labs/mcp-go#199</a></li>
<li>fix(client): potential risk of sending on closed channel by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/194">mark3labs/mcp-go#194</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/TBXark"><code>@​TBXark</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/197">mark3labs/mcp-go#197</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.23.0...v0.23.1">https://github.com/mark3labs/mcp-go/compare/v0.23.0...v0.23.1</a></p>
<h2>Release v0.23.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Export SendNotificationToAllClients by <a
href="https://github.com/scottfeldman"><code>@​scottfeldman</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/176">mark3labs/mcp-go#176</a></li>
<li>feat(server): Add hooks.AddOnUnregisterSession functionality by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/175">mark3labs/mcp-go#175</a></li>
<li>Refact: pre-allocate memory for memory-efficiency by <a
href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/178">mark3labs/mcp-go#178</a></li>
<li>fix sse shutdown by <a
href="https://github.com/karngyan"><code>@​karngyan</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/128">mark3labs/mcp-go#128</a></li>
<li>fix: update spec link by <a
href="https://github.com/warjiang"><code>@​warjiang</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/188">mark3labs/mcp-go#188</a></li>
<li>Add <code>InProcessTransport</code> by <a
href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/189">mark3labs/mcp-go#189</a></li>
<li>Optimize capability and notification according to specification by
<a href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> in
<a
href="https://redirect.github.com/mark3labs/mcp-go/pull/184">mark3labs/mcp-go#184</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/scottfeldman"><code>@​scottfeldman</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/176">mark3labs/mcp-go#176</a></li>
<li><a href="https://github.com/cryo-zd"><code>@​cryo-zd</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/178">mark3labs/mcp-go#178</a></li>
<li><a href="https://github.com/karngyan"><code>@​karngyan</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/128">mark3labs/mcp-go#128</a></li>
<li><a href="https://github.com/warjiang"><code>@​warjiang</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/188">mark3labs/mcp-go#188</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.22.0...v0.23.0">https://github.com/mark3labs/mcp-go/compare/v0.22.0...v0.23.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/edda393a1a231aefaaef41086ba7344e30c6b559"><code>edda393</code></a>
fix potential risk of sending on closed channel (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/194">#194</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/6e000c30767a9e03f90d2a3932af91c620945323"><code>6e000c3</code></a>
check stdio start before sending notification (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/199">#199</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/fb13cfbf97dfa75c4245e3924a8e9ced99871a55"><code>fb13cfb</code></a>
fix: correct JSON key for client capabilities (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/197">#197</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/d343bff720e8ce4c21415dd7bb253bd107d2d0d7"><code>d343bff</code></a>
fix(client): prevent panics (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/192">#192</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/781b7327ad04888293d38d0bf0a9cd0588d3af79"><code>781b732</code></a>
optimize capability and notification (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/184">#184</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/6760d870f40fa9df86a733170d2d3951ebe5659c"><code>6760d87</code></a>
in process transport (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/189">#189</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/be0d8cbfe8cefde1ad0116b76b4abebd93bf323f"><code>be0d8cb</code></a>
fix: update spec link (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/188">#188</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/2e4af4cf0c6dd36013aeb725f547ad4963c2155d"><code>2e4af4c</code></a>
fix sse shutdown (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/128">#128</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/9f39a43b4e9d756e386289dd687f57cf9ffacfe0"><code>9f39a43</code></a>
Merge branch 'main' of github.com:mark3labs/mcp-go</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/dd7dcc515d62b442b53b1789a4d41959547719a3"><code>dd7dcc5</code></a>
Fix spelling</li>
<li>Additional commits viewable in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.22.0...v0.23.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.22.0&new-version=0.23.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 12:20:30 +00:00
Danny Kopping e0483e3136 feat: add prebuilds metrics collector (#17547)
Closes https://github.com/coder/internal/issues/509

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-04-28 12:28:56 +02:00
Hugo Dutka b47d54d777 chore: cache terraform providers between CI test runs (#17373)
Addresses https://github.com/coder/internal/issues/322.

This PR starts caching Terraform providers used by `TestProvision` in
`provisioner/terraform/provision_test.go`. The goal is to improve the
reliability of this test by cutting down on the number of network calls
to external services. It leverages GitHub Actions cache, which [on depot
runners is persisted for 14 days by
default](https://depot.dev/docs/github-actions/overview#cache-retention-policy).

Other than the aforementioned `TestProvision`, I couldn't find any other
tests which depend on external terraform providers.
2025-04-28 10:57:24 +02:00
Danny Kopping 08ad910171 feat: add prebuilds configuration & bootstrapping (#17527)
Closes https://github.com/coder/internal/issues/508

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Cian Johnston <cian@coder.com>
2025-04-25 11:07:15 +02:00
Jaayden Halko e562e3c882 chore: mark parameters as required (#17551)
This adds a red asterisk next to a parameter name if it is required and
marks passes the parameter required value to input and textarea form
controls.

The multi-select combobox needs additional work (in a separate PR) so
that it can handle the required prop correctly for form submit.

<img width="544" alt="Screenshot 2025-04-24 at 00 02 10"
src="https://github.com/user-attachments/assets/5c6758d3-41a4-444d-b7e9-e1fe011703d3"
/>
2025-04-24 17:14:21 -04:00
M Atif Ali fc921a584f chore(docs): update release calendar dates and next release calculation (#17560) 2025-04-24 19:42:33 +05:00
Yevhenii Shcherbina 118f12ac3a feat: implement claiming of prebuilt workspaces (#17458)
Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Danny Kopping <danny@coder.com>
Co-authored-by: Edward Angert <EdwardAngert@users.noreply.github.com>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Jaayden Halko <jaayden.halko@gmail.com>
Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
Co-authored-by: Aericio <16523741+Aericio@users.noreply.github.com>
Co-authored-by: M Atif Ali <me@matifali.dev>
Co-authored-by: Michael Suchacz <203725896+ibetitsmike@users.noreply.github.com>
2025-04-24 09:39:38 -04:00
dependabot[bot] 25dacd39e7 chore: bump github.com/prometheus-community/pro-bing from 0.6.0 to 0.7.0 (#17378)
Bumps
[github.com/prometheus-community/pro-bing](https://github.com/prometheus-community/pro-bing)
from 0.6.0 to 0.7.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prometheus-community/pro-bing/releases">github.com/prometheus-community/pro-bing's
releases</a>.</em></p>
<blockquote>
<h2>v0.7.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Synchronize common files from prometheus/prometheus by <a
href="https://github.com/prombot"><code>@​prombot</code></a> in <a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/146">prometheus-community/pro-bing#146</a></li>
<li>Bump golang.org/x/net from 0.34.0 to 0.35.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/147">prometheus-community/pro-bing#147</a></li>
<li>Bump golang.org/x/sync from 0.10.0 to 0.11.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/148">prometheus-community/pro-bing#148</a></li>
<li>Update Go by <a
href="https://github.com/SuperQ"><code>@​SuperQ</code></a> in <a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/152">prometheus-community/pro-bing#152</a></li>
<li>Bump golang.org/x/net from 0.35.0 to 0.38.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/150">prometheus-community/pro-bing#150</a></li>
<li>Bump golang.org/x/sync from 0.11.0 to 0.13.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/153">prometheus-community/pro-bing#153</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prometheus-community/pro-bing/compare/v0.6.1...v0.7.0">https://github.com/prometheus-community/pro-bing/compare/v0.6.1...v0.7.0</a></p>
<h2>v0.6.1</h2>
<h2>What's Changed</h2>
<ul>
<li>fix/stats race by <a
href="https://github.com/perhallgren"><code>@​perhallgren</code></a> in
<a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/145">prometheus-community/pro-bing#145</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/perhallgren"><code>@​perhallgren</code></a>
made their first contribution in <a
href="https://redirect.github.com/prometheus-community/pro-bing/pull/145">prometheus-community/pro-bing#145</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prometheus-community/pro-bing/compare/v0.6.0...v0.6.1">https://github.com/prometheus-community/pro-bing/compare/v0.6.0...v0.6.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/85df87ee97d5a448f5bc5c2ccc6f43d54e68b0cd"><code>85df87e</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus-community/pro-bing/issues/153">#153</a>
from prometheus-community/dependabot/go_modules/golan...</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/4df7cf6d8a2e926bd84f0c23ef3c70d207e08648"><code>4df7cf6</code></a>
Bump golang.org/x/sync from 0.11.0 to 0.13.0</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/0748554038ca051940674fa98cf8ae470b0bfb2d"><code>0748554</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus-community/pro-bing/issues/150">#150</a>
from prometheus-community/dependabot/go_modules/golan...</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/0a802c09eea30c0d7232e5b23cd02ac0a0063bb0"><code>0a802c0</code></a>
Bump golang.org/x/net from 0.35.0 to 0.38.0</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/a184532955ba6a987d1a2b406ab2708c41e9b9d0"><code>a184532</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus-community/pro-bing/issues/152">#152</a>
from prometheus-community/superq/bump_go</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/ed8beb88ca19f00c9d5dfc8f93f99733366c89aa"><code>ed8beb8</code></a>
Update Go</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/c9b2c133ccf6c6212f29ca33c6258f7400ea76f6"><code>c9b2c13</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus-community/pro-bing/issues/148">#148</a>
from prometheus-community/dependabot/go_modules/golan...</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/b3180894e532d3a854cb025d889e50e4cac5f9fe"><code>b318089</code></a>
Bump golang.org/x/sync from 0.10.0 to 0.11.0</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/ba53383b80d9cd150307779f2d7e09ef3985f689"><code>ba53383</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus-community/pro-bing/issues/147">#147</a>
from prometheus-community/dependabot/go_modules/golan...</li>
<li><a
href="https://github.com/prometheus-community/pro-bing/commit/a683c097aea7c567a2d4e4c91b001822fbe48850"><code>a683c09</code></a>
Bump golang.org/x/net from 0.34.0 to 0.35.0</li>
<li>Additional commits viewable in <a
href="https://github.com/prometheus-community/pro-bing/compare/v0.6.0...v0.7.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/prometheus-community/pro-bing&package-manager=go_modules&previous-version=0.6.0&new-version=0.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 09:45:15 +00:00
M Atif Ali c45343aa99 chore(dogfood): add windsurf module (#17558) 2025-04-24 14:14:50 +05:00
M Atif Ali 166d88e279 docs: add automatic release calendar updates in docs (#17531) 2025-04-24 13:52:34 +05:00
M Atif Ali ad38a3bddc fix(examples/templates/kubernetes-devcontainer): update coder provider (#17555) 2025-04-24 12:56:07 +05:00
Michael Suchacz 9922240fd4 feat: enable masking password inputs instead of blocking echo (#17469)
Closes #17059
2025-04-24 09:54:00 +02:00
Aericio 614a7d0d58 fix(examples/templates/docker-devcontainer): update folder path and provider version constraint (#17553)
Co-authored-by: M Atif Ali <me@matifali.dev>
2025-04-24 07:21:35 +00:00
M Atif Ali 4759e17acd chore(dogfood): allow provider minor version updates (#17554) 2025-04-24 07:21:31 +00:00
Ethan 4f70b596dc ci: move go install tools to separate action (#17552)
I think using an older version of mockgen on the schmoder CI broke the
workflow, so I'm gonna sync it via this action, like we do with the
other `make build` dependencies.
2025-04-24 03:02:57 +00:00
Jaayden Halko ef6e6e41ff fix: add websocket close handling (#17548)
resolves #17508 

Display an error in the UI that the websocket closed if the user is
still interacting with the dynamic parameters form

<img width="795" alt="Screenshot 2025-04-23 at 17 57 25"
src="https://github.com/user-attachments/assets/15362ddb-fe01-462e-8537-a48302c5c621"
/>
2025-04-23 19:19:25 -04:00
Edward Angert 3567d455a7 docs: fix ssh coder example in testing-templates doc (#17550)
from @NickSquangler and @angrycub on Slack

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-23 16:13:13 -04:00
Edward Angert e6facaa41b docs: clarify that parameter autofill requires experimental flag (#17546)
Update documentation to indicate that parameter autofill requires
`--experiments=auto-fill-parameters` enabled

Fixes #14673

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-23 17:13:08 +00:00
Jaayden Halko 03eeb01247 chore: use new table design for markdown rendering (#17530)
resolves #17502 

<img width="756" alt="Screenshot 2025-04-23 at 11 26 19"
src="https://github.com/user-attachments/assets/667c595c-21de-496c-8f25-3dca9f840c7c"
/>
2025-04-23 13:02:14 -04:00
Jaayden Halko 3306f0f2a2 fix: fix broken img layout (#17525)
resolves #17507 

Before

<img width="629" alt="Screenshot 2025-04-23 at 11 01 55"
src="https://github.com/user-attachments/assets/79e2945b-0301-4cf5-9b25-f112bac9c2ff"
/>

After

<img width="629" alt="Screenshot 2025-04-23 at 11 02 45"
src="https://github.com/user-attachments/assets/c74d3c03-ebee-42e6-bd16-b4610139cb86"
/>
2025-04-23 13:01:36 -04:00
Jaayden Halko c1162eb9a8 fix: only highlight checkbox on hover when checkbox is enabled (#17526)
resolves #17503
2025-04-23 13:01:02 -04:00
ケイラ 36a72a2b25 chore: loosen static validation when using dynamic parameters (#17516)
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
2025-04-23 10:15:49 -06:00
ケイラ 3b4343ddf3 fix: fix workspace creation on template page (#17518) 2025-04-23 09:44:36 -06:00
Edward Angert 5a7d531aef docs: edit the ai agents doc (#17521)
general edit and adding some highlights as I work through the section

[preview](https://coder.com/docs/@ai-coder-edit/ai-coder/agents)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-23 11:14:57 -04:00
Edward Angert 9dea568027 docs: document GIT_ASKPASS for OAuth connections (#17457)
closes #17375 

from @ericpaulsen 

> a prospect recently inquired about how our OAuth integration with
GitLab works, and I realized we do not have any information on
`GIT_ASKPASS` is used to retreive the OAuth token for users when they
run `git` operations.

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-23 11:14:15 -04:00
Bruno Quaresma 88589ef32f fix: fix build timeline scale for longer builds (#17514)
Fix https://github.com/coder/coder/issues/15374
2025-04-23 11:34:08 -03:00
Steven Masley 71dbd0c888 fix: nil ptr deref when removing OIDC from deployment and accessing old users (#17501)
If OIDC is removed from a deployment, trying to create a workspace for a previous user
on OIDC would panic.
2025-04-23 08:45:26 -05:00
Mathias Fredriksson c106aee0d6 fix(scripts/release): handle cherry-pick bot titles in check commit metadata (#17535) 2025-04-23 12:20:00 +00:00
Danny Kopping b3cc8e56d2 chore: set timezone on all golden file make targets (#17533)
We replace timestamps in our golden files to keep the values constant.

However, if a non-UTC timezone is used then the timestamp will still be
replaced but the whitespace will be messed up (since it was aligned to
the original value).


![image](https://github.com/user-attachments/assets/b7ebf615-5b41-41bb-8939-682a45a61952)

Therefore we must force a timezone when generating golden files.

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-04-23 11:26:46 +00:00
Mathias Fredriksson 35553a5815 chore(Makefile): fix incorrect redirection of output (#17532) 2025-04-23 11:01:28 +00:00
Mathias Fredriksson 1ba02f4297 chore(dogfood): increase container graceful stop time (#17528)
Fixes workspace stop when you've run `devcontainer up` in coder/coder.

The previous attempt in #17110 gave insufficient time.
2025-04-23 13:40:51 +03:00
Spike Curtis 0ef7d0b3e5 docs: correct low MTU troubleshooting language (#17468)
Fixes docs troubleshooting language around low MTU. In fact, we see
conenctions hanging rather than just showing low performance, since
packets are dropped rather than fragmented.

---------

Co-authored-by: Edward Angert <EdwardAngert@users.noreply.github.com>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-23 10:00:33 +04:00
Dean Sheather b15d060410 fix(agent): return listed drives on failure on windows (#17505)
The behavior of the partitions listing function from gopsutil is that it
will return all partitions that didn't fail to be read, but will return
something similar to a multierror.

Errors are now ignored unless there are no drives returned.
2025-04-23 03:31:43 +10:00
Steven Masley ca38729840 chore: revert dynamic params as a safe experiment (#17510) 2025-04-22 16:21:15 +00:00
Steven Masley 5d97d82422 chore: update coder/preview dep (#17512)
Using latest release of coder/preview
2025-04-22 16:21:01 +00:00
Bruno Quaresma 83b2c9bf41 fix: don't show promote button for members (#17511)
Fix https://github.com/coder/coder/issues/15850
2025-04-22 12:50:46 -03:00
Eric Paulsen cbc699b6df chore: set default requests/limits in helm chart (#16844)
closes #16825 - my first commit from across the pond 😄

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-22 11:05:34 +01:00
Dean Sheather d566008087 fix: update tailscale to improve block endpoints functionality (#17496)
Direct endpoints from the peer will no longer be processed.
2025-04-22 09:32:21 +00:00
Jaayden Halko afb175d9ee chore: make dynamic params a valid experiment (#17492) 2025-04-22 05:09:16 -04:00
Cian Johnston 444bd6a212 fix(cli/server.go): switch to alternate maven repo for postgres binaries (#17451)
Not really guaranteed, but worth a shot.

---------

Co-authored-by: Danny Kopping <danny@coder.com>
2025-04-22 09:02:35 +01:00
Jaayden Halko 56ee5d8f1b fix: update dynamic params styles (#17489)
1. increase form width and adjust form field width #17471 
2. Move slider value display as its currently broken for long parameter
titles and descriptions
3. increase the height of the slider
4. automatically increase the height of the textarea as the user types
#17472
2025-04-21 17:50:57 -04:00
dependabot[bot] 823d3ea64e chore: bump google.golang.org/grpc from 1.71.0 to 1.72.0 (#17481)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from
1.71.0 to 1.72.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/grpc/grpc-go/releases">google.golang.org/grpc's
releases</a>.</em></p>
<blockquote>
<h2>Release 1.72.0</h2>
<h1>Dependencies</h1>
<ul>
<li>Minimum supported Go version is now 1.23 (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8108">#8108</a>)</li>
</ul>
<h1>API Changes</h1>
<ul>
<li>resolver: add experimental <code>AddressMapV2</code> with generics
to ultimately replace <code>AddressMap</code>. Deprecate
<code>AddressMap</code> for deletion (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8187">#8187</a>)</li>
<li>resolver: convert EndpointMap in place to use generics (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8189">#8189</a>)</li>
</ul>
<h1>New Features</h1>
<ul>
<li>xds: add <code>grpc.xds_client.server_failure</code> counter metric
on xDS client to record connectivity errors (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8203">#8203</a>)</li>
<li>balancer/rls: allow <code>maxAge</code> to exceed 5 minutes if
<code>staleAge</code> is set in the LB policy configuration (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8137">#8137</a>)</li>
<li>ringhash: implement <a
href="https://github.com/grpc/proposal/blob/master/A76-ring-hash-improvements.md">gRFC
A76</a> improvements. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8159">#8159</a>)</li>
</ul>
<h1>Bug Fixes</h1>
<ul>
<li>xds: fix support for circuit breakers and load reporting in
LOGICAL_DNS clusters (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8169">#8169</a>,
<a
href="https://redirect.github.com/grpc/grpc-go/issues/8170">#8170</a>)</li>
<li>cds: improve RPC error messages when resources are not found (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8122">#8122</a>)</li>
<li>priority: fix race that could leak balancers and goroutines during
shutdown (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8095">#8095</a>)</li>
<li>stats/opentelemetry: fix trace attributes message sequence numbers
to start from 0 (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8237">#8237</a>)</li>
<li>balancer/pickfirstleaf: fix panic if deprecated Address.Metadata
field is set to a non-comparable value by ignoring the field (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8227">#8227</a>)</li>
</ul>
<h1>Behavior Changes</h1>
<ul>
<li>transport: make servers send an HTTP/2 RST_STREAM frame to cancel a
stream when the deadline expires (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8071">#8071</a>)</li>
</ul>
<h1>Documentation</h1>
<ul>
<li>stats: clarify the expected sequence of events on a stats handler
(<a
href="https://redirect.github.com/grpc/grpc-go/issues/7885">#7885</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/RyanBlaney"><code>@​RyanBlaney</code></a></li>
</ul>
</li>
</ul>
<h2>Release 1.71.1</h2>
<h1>Bug Fixes</h1>
<ul>
<li>grpc: fix a bug causing an extra Read from the compressor if a
compressed message is the same size as the limit. This could result in a
panic with the built-in gzip compressor (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8178">#8178</a>)</li>
<li>xds: restore the behavior of reading the bootstrap config before
creating the first xDS client instead of at package init time (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8164">#8164</a>)</li>
<li>stats/opentelemetry: use <code>TextMapPropagator</code> and
<code>TracerProvider</code> from <code>TraceOptions</code> instead of
OpenTelemetry globals (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8166">#8166</a>)</li>
<li>client: fix races when an http proxy is configured that could lead
to deadlocks or panics (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8195">#8195</a>)</li>
<li>client: fix bug causing RPC failures with message &quot;no children
to pick from&quot; when using a custom resolver that calls the
deprecated <code>NewAddress</code> API (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8149">#8149</a>)</li>
<li>wrr: fix slow processing of address updates that could result in
problems including RPC failures for servers with a large number of
backends (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8179">#8179</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/grpc/grpc-go/commit/a43eba6fed49b81b84cfdba85c356aca22086d7e"><code>a43eba6</code></a>
Change version to 1.72.0 (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8218">#8218</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/48f48c14f7a670d4405680d4ae121b557ae89f55"><code>48f48c1</code></a>
balancer/pickfirstleaf: Avoid reading Address.Metadata (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8227">#8227</a>)
(<a
href="https://redirect.github.com/grpc/grpc-go/issues/8259">#8259</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/fd6f5852919a08d9a5aaa421c2910405da6a5ed0"><code>fd6f585</code></a>
Cherry-pick <a
href="https://redirect.github.com/grpc/grpc-go/issues/8159">#8159</a>
and <a
href="https://redirect.github.com/grpc/grpc-go/issues/8243">#8243</a> to
v1.72.x (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8255">#8255</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/79ca1744edd19936966a4ef45bcef2d240587812"><code>79ca174</code></a>
stats/opentelemetry: fix trace attributes message sequence numbers to
start f...</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/57a2605e35a0608f1cbdb1e471db94d2a28ec42c"><code>57a2605</code></a>
xdsclient: fix TestServerFailureMetrics_BeforeResponseRecv test to wait
for w...</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/5edab9e55414068e74320716117a2659c5d2174e"><code>5edab9e</code></a>
xdsclient: add grpc.xds_client.server_failure counter mertric (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8203">#8203</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/78ba6616c1c3d641cf2cc861a0696fd5beb90aa3"><code>78ba661</code></a>
regenerate protos (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8208">#8208</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/6819ed796fcd0232a46dab21c1b7826aa7f1d561"><code>6819ed7</code></a>
delegatingresolver: Stop calls into delegates once the parent resolver
is clo...</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/a51009d1d7074ee1efcd323578064cbe44ef87e5"><code>a51009d</code></a>
resolver: convert EndpointMap to use generics (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8189">#8189</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/b0d120384670bde5a2fa830d65e43b250c24d8fd"><code>b0d1203</code></a>
resolver: create AddressMapV2 with generics to replace AddressMap (<a
href="https://redirect.github.com/grpc/grpc-go/issues/8187">#8187</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/grpc/grpc-go/compare/v1.71.0...v1.72.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/grpc&package-manager=go_modules&previous-version=1.71.0&new-version=1.72.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 18:00:54 +00:00
dependabot[bot] 36625af3bc chore: bump google.golang.org/api from 0.228.0 to 0.229.0 (#17480)
Bumps
[google.golang.org/api](https://github.com/googleapis/google-api-go-client)
from 0.228.0 to 0.229.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/releases">google.golang.org/api's
releases</a>.</em></p>
<blockquote>
<h2>v0.229.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.228.0...v0.229.0">0.229.0</a>
(2025-04-14)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3082">#3082</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ab1e35bd922013503c83b13ceeca77261b161bbc">ab1e35b</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3084">#3084</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/eab21799a214ec6b03e74ea0c8c1bde79c851faf">eab2179</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3085">#3085</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9af4079c0c6bab3c5567b42888be725bfc47b3b0">9af4079</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3086">#3086</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9c927b65141cbfc1019dbc4350836fb363167de9">9c927b6</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3087">#3087</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3c387cdc0b26846f2c2ae02f9871020fe732c87d">3c387cd</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3089">#3089</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/b64e7929166b212d1721afd68bf9fe8d40dc5775">b64e792</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3090">#3090</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/65fc9d3edb75cb38ceb96a383dcf6d7fee89662e">65fc9d3</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3093">#3093</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3a51a3a77ef75d10dc75fb4af0e5c791809cb568">3a51a3a</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3094">#3094</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ca845161fd6688acdf5818fcb06f91d314866e4c">ca84516</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3096">#3096</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9e992f492d43134b44b0a830e99c8b78dd8fc524">9e992f4</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3097">#3097</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c09b6a9455c6aab4dbd7422245e4c9b2502c5806">c09b6a9</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3099">#3099</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/66d217562f865a6e93e9cd680c2e65cd815c441a">66d2175</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3101">#3101</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9ad998bc308b688bb47fd1621d73789bc66ec565">9ad998b</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3102">#3102</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/70d6fb25935cb233a3d8cdc144d04add6f1ed5f9">70d6fb2</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3103">#3103</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/414e575ddac0ec40cbd77dccb2b376f2a16c7675">414e575</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3104">#3104</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/91f658957210bd86c3365cbed6d7753a3cc7ff07">91f6589</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3105">#3105</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1c5ea6cfdd2437d3d2f790a5ab252b070e68bbbe">1c5ea6c</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3106">#3106</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/fabfddf97037bebce44fbbd9b85473a621649802">fabfddf</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3107">#3107</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ecbc1a9e09191e81577ac480e32234b9d146d217">ecbc1a9</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md">google.golang.org/api's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.228.0...v0.229.0">0.229.0</a>
(2025-04-14)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3082">#3082</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ab1e35bd922013503c83b13ceeca77261b161bbc">ab1e35b</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3084">#3084</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/eab21799a214ec6b03e74ea0c8c1bde79c851faf">eab2179</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3085">#3085</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9af4079c0c6bab3c5567b42888be725bfc47b3b0">9af4079</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3086">#3086</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9c927b65141cbfc1019dbc4350836fb363167de9">9c927b6</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3087">#3087</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3c387cdc0b26846f2c2ae02f9871020fe732c87d">3c387cd</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3089">#3089</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/b64e7929166b212d1721afd68bf9fe8d40dc5775">b64e792</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3090">#3090</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/65fc9d3edb75cb38ceb96a383dcf6d7fee89662e">65fc9d3</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3093">#3093</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3a51a3a77ef75d10dc75fb4af0e5c791809cb568">3a51a3a</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3094">#3094</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ca845161fd6688acdf5818fcb06f91d314866e4c">ca84516</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3096">#3096</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9e992f492d43134b44b0a830e99c8b78dd8fc524">9e992f4</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3097">#3097</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c09b6a9455c6aab4dbd7422245e4c9b2502c5806">c09b6a9</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3099">#3099</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/66d217562f865a6e93e9cd680c2e65cd815c441a">66d2175</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3101">#3101</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/9ad998bc308b688bb47fd1621d73789bc66ec565">9ad998b</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3102">#3102</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/70d6fb25935cb233a3d8cdc144d04add6f1ed5f9">70d6fb2</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3103">#3103</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/414e575ddac0ec40cbd77dccb2b376f2a16c7675">414e575</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3104">#3104</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/91f658957210bd86c3365cbed6d7753a3cc7ff07">91f6589</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3105">#3105</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1c5ea6cfdd2437d3d2f790a5ab252b070e68bbbe">1c5ea6c</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3106">#3106</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/fabfddf97037bebce44fbbd9b85473a621649802">fabfddf</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3107">#3107</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/ecbc1a9e09191e81577ac480e32234b9d146d217">ecbc1a9</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/8448bf2ae14fbf6a239ceea036ab6b69930db02a"><code>8448bf2</code></a>
chore(main): release 0.229.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3083">#3083</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/8dd21ed8ab64b874d31b1096edf6923b0f9e1912"><code>8dd21ed</code></a>
chore(all): update cloud.google.com/go/auth to v0.16.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3109">#3109</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/ac04e77c5460d05f02165272051ffb006dab01ae"><code>ac04e77</code></a>
chore(all): update all (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3108">#3108</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/ecbc1a9e09191e81577ac480e32234b9d146d217"><code>ecbc1a9</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3107">#3107</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/fabfddf97037bebce44fbbd9b85473a621649802"><code>fabfddf</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3106">#3106</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/1c5ea6cfdd2437d3d2f790a5ab252b070e68bbbe"><code>1c5ea6c</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3105">#3105</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/91f658957210bd86c3365cbed6d7753a3cc7ff07"><code>91f6589</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3104">#3104</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/414e575ddac0ec40cbd77dccb2b376f2a16c7675"><code>414e575</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3103">#3103</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/70d6fb25935cb233a3d8cdc144d04add6f1ed5f9"><code>70d6fb2</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3102">#3102</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/f7272c9d0bb58186d5ddab19f4671ac67c914915"><code>f7272c9</code></a>
chore(all): update all (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3100">#3100</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/googleapis/google-api-go-client/compare/v0.228.0...v0.229.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/api&package-manager=go_modules&previous-version=0.228.0&new-version=0.229.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 17:48:34 +00:00
ケイラ f6364a2f6e feat: add opt-out option to new parameters form (#17456)
Closes https://github.com/coder/preview/issues/62
2025-04-21 10:44:44 -06:00
dependabot[bot] c0ca47d015 chore: bump github.com/charmbracelet/glamour from 0.9.1 to 0.10.0 (#17476)
Bumps
[github.com/charmbracelet/glamour](https://github.com/charmbracelet/glamour)
from 0.9.1 to 0.10.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/charmbracelet/glamour/releases">github.com/charmbracelet/glamour's
releases</a>.</em></p>
<blockquote>
<h2>v0.10.0</h2>
<h1>Actually readable tables</h1>
<p>Big tables that included links were always hard to read. Links can be
very long, and tables often have limited space to render them. This
means that links often took the space of many lines and weren't properly
clickable because they were being truncated in practice.</p>
<p>Starting on this release, Glamour will render links and images at the
footer of the table, with a reference number so you can easily find the
link you're looking for. If you want the old behavior, it is still
supported via the new <code>WithInlineTableLinks</code> option.</p>
<h2>The New Way</h2>
<p><img
src="https://github.com/user-attachments/assets/9ea84076-c318-4835-b5be-a583745a4953"
alt="table_with_footer_links_and_images" /></p>
<h2>The Old Way</h2>
<p>Wanna render tables with inline links? You still can:</p>
<pre lang="go"><code>r, err :=
glamour.NewTermRenderer(glamour.WithInlineTableLinks(true))
if err != nil { /*...*/ }
<p>out, err := r.RenderBytes(in)<br />
if err != nil { /<em>...</em>/ }</p>
<p>fmt.Fprintf(os.Stdout, &quot;%s\n&quot;, out)<br />
</code></pre></p>
<p><img
src="https://github.com/user-attachments/assets/de3d3d33-9592-44ea-99d2-f3d8e9e94f9c"
alt="table_with_inline_links_and_images" /></p>
<h1>Prettier GitHub links</h1>
<p>We also introduced a change so that GitHub links inside tables that
reference issues, discussions or PRs will be shown in its shortened
form, similar to how GitHub itself present the links on issue
descriptions: <code>owner/repo#123</code>.</p>
<p><img
src="https://github.com/user-attachments/assets/8adb2498-a361-4749-8e98-02f17d4f9062"
alt="table_with_footer_auto_links_short" /></p>
<h1>Extra</h1>
<p>Also, we introduced <code>WithTableWrap</code>, so you can disable
table text wrapping if really want:</p>
<pre lang="go"><code>r, err :=
glamour.NewTermRenderer(glamour.WithTableWrap(false))
if err != nil { ... }
<p>out, err := r.RenderBytes(in)<br />
if err != nil { ... }</p>
<p>fmt.Fprintf(os.Stdout, &quot;%s\n&quot;, out)<br />
</code></pre></p>
<h2>Changelog</h2>
<h3>New Features</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/charmbracelet/glamour/commit/05ee9b5f4dcf3e4426c4ba41e1f9d7ea4f34d603"><code>05ee9b5</code></a>
v0.10.0</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/c9af0458d403e584402ff683e0e8403a194d73d3"><code>c9af045</code></a>
feat(tables): format github links inside tables in a more readable
manner</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/f2eb484a992f6a31bad968205b6d63719b8c7fa2"><code>f2eb484</code></a>
feat: add autolink package with patterns for more readable github
urls</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/9d873734c11cf9d1e29853643a751624042df3b0"><code>9d87373</code></a>
feat(table): pad position on table link list</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/a11e9a0c3a66a55d411a0aa4dcd6685d4ba9d823"><code>a11e9a0</code></a>
feat(table): show position of link also inside the table</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/42f47a22f34bbbf73421210e7aff4f6438ffd052"><code>42f47a2</code></a>
feat(table): prefix all links with the position in the footer</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/61cfc45c6bcd582a4d0ca810690d668f276ede13"><code>61cfc45</code></a>
feat(table): add ability to render links at the bottom</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/5437e4a1a7dfc095a4afe063feaab079ab5a9629"><code>5437e4a</code></a>
fix: ensure that prop is always cleared</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/60534f9196f23ed0849ba1ac05df41325d8968b5"><code>60534f9</code></a>
chore(deps): bump golang.org/x/term from 0.30.0 to 0.31.0 (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/418">#418</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/606f55a8d8fe2adc7251ad2e269fe9f4a32a0172"><code>606f55a</code></a>
chore(deps): bump golang.org/x/text from 0.23.0 to 0.24.0 (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/419">#419</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/charmbracelet/glamour/compare/v0.9.1...v0.10.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/charmbracelet/glamour&package-manager=go_modules&previous-version=0.9.1&new-version=0.10.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 16:06:47 +00:00
Bruno Quaresma 6c1f0d42dd fix: fix empty workspaces result (#17484)
After refactoring the workspaces table to use the new table
components://github.com/coder/coder/pull/17404), the empty styles got
broken. You can see the related PR
[here](https://github.com/coder/coder/pull/17404).

Before:

![image](https://github.com/user-attachments/assets/9592d65c-9a63-4d22-8a01-8a1ce174422e)

After:
<img width="1210" alt="Screenshot 2025-04-21 at 10 34 19"
src="https://github.com/user-attachments/assets/6545d078-80f1-4251-8816-04eb0f41e848"
/>
2025-04-21 10:45:26 -03:00
dependabot[bot] a1925bccd7 chore: bump github.com/coder/terraform-provider-coder/v2 from 2.4.0-pre0 to 2.4.0-pre1 (#17483)
Bumps
[github.com/coder/terraform-provider-coder/v2](https://github.com/coder/terraform-provider-coder)
from 2.4.0-pre0 to 2.4.0-pre1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/coder/terraform-provider-coder/releases">github.com/coder/terraform-provider-coder/v2's
releases</a>.</em></p>
<blockquote>
<h2>v2.4.0-pre1</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: add the option to debug the coder terraform provider by <a
href="https://github.com/SasSwart"><code>@​SasSwart</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/378">coder/terraform-provider-coder#378</a></li>
<li>chore: enhance parameter validation error messages by <a
href="https://github.com/Emyrk"><code>@​Emyrk</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/379">coder/terraform-provider-coder#379</a></li>
<li>chore: update to go 1.24.1 by <a
href="https://github.com/johnstcn"><code>@​johnstcn</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/382">coder/terraform-provider-coder#382</a></li>
<li>build(deps): Bump golang.org/x/crypto from 0.33.0 to 0.35.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/coder/terraform-provider-coder/pull/380">coder/terraform-provider-coder#380</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/coder/terraform-provider-coder/compare/v2.4.0-pre0...v2.4.0-pre1">https://github.com/coder/terraform-provider-coder/compare/v2.4.0-pre0...v2.4.0-pre1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/e51ae3aff8c4c0c3c0559841fabb59eafea1f86a"><code>e51ae3a</code></a>
build(deps): Bump golang.org/x/crypto from 0.33.0 to 0.35.0 (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/380">#380</a>)</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/e40c9b9278ad0a7574bbeb067e2119f850b0df5c"><code>e40c9b9</code></a>
chore: update to go 1.24.2 (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/382">#382</a>)</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/f66adaca2adfb6b19108200483855c4023fcc982"><code>f66adac</code></a>
chore: enhance parameter validation error messages (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/379">#379</a>)</li>
<li><a
href="https://github.com/coder/terraform-provider-coder/commit/53a68cd7496371d6f325f9c7bd8c6808069c4664"><code>53a68cd</code></a>
feat: add the option to debug the coder terraform provider (<a
href="https://redirect.github.com/coder/terraform-provider-coder/issues/378">#378</a>)</li>
<li>See full diff in <a
href="https://github.com/coder/terraform-provider-coder/compare/v2.4.0-pre0...v2.4.0-pre1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/coder/terraform-provider-coder/v2&package-manager=go_modules&previous-version=2.4.0-pre0&new-version=2.4.0-pre1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 12:59:04 +00:00
dependabot[bot] 54b2b7a689 chore: bump github.com/mark3labs/mcp-go from 0.20.1 to 0.22.0 (#17482)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.20.1 to 0.22.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.22.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: add mutex to SSEServer to avoid data race between Start and
Shutdown; fix test error on Windows (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/166">#166</a>
<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/172">#172</a>)
by <a href="https://github.com/Wood-Q"><code>@​Wood-Q</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/170">mark3labs/mcp-go#170</a></li>
<li>feat(server): convert ping messages to be spec compliant by <a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/169">mark3labs/mcp-go#169</a></li>
<li>feat: Implement Streamable-HTTP Client Basic by <a
href="https://github.com/leavez"><code>@​leavez</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/168">mark3labs/mcp-go#168</a></li>
<li>feat:Added the parameter parsing mode to parse any to the specified
type by <a href="https://github.com/hl540"><code>@​hl540</code></a> in
<a
href="https://redirect.github.com/mark3labs/mcp-go/pull/148">mark3labs/mcp-go#148</a></li>
<li>Add RemoveResource method to MCPServer by <a
href="https://github.com/isaacphi"><code>@​isaacphi</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/141">mark3labs/mcp-go#141</a></li>
<li>feat: add message to ProgressNotification by <a
href="https://github.com/xhdd123321"><code>@​xhdd123321</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/119">mark3labs/mcp-go#119</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Wood-Q"><code>@​Wood-Q</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/170">mark3labs/mcp-go#170</a></li>
<li><a
href="https://github.com/robert-jackson-glean"><code>@​robert-jackson-glean</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/169">mark3labs/mcp-go#169</a></li>
<li><a href="https://github.com/hl540"><code>@​hl540</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/148">mark3labs/mcp-go#148</a></li>
<li><a href="https://github.com/isaacphi"><code>@​isaacphi</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/141">mark3labs/mcp-go#141</a></li>
<li><a
href="https://github.com/xhdd123321"><code>@​xhdd123321</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/119">mark3labs/mcp-go#119</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.21.1...v0.22.0">https://github.com/mark3labs/mcp-go/compare/v0.21.1...v0.22.0</a></p>
<h2>Release v0.21.1</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: tool annotation by <a
href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/165">mark3labs/mcp-go#165</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.21.0...v0.21.1">https://github.com/mark3labs/mcp-go/compare/v0.21.0...v0.21.1</a></p>
<h2>Release v0.21.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Add DefaultArray by <a
href="https://github.com/tiborvass"><code>@​tiborvass</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/67">mark3labs/mcp-go#67</a></li>
<li>Unified Client Transport Layer for Streamable HTTP Support by <a
href="https://github.com/leavez"><code>@​leavez</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/114">mark3labs/mcp-go#114</a></li>
<li>fix(tools): add <code>omitempty</code> to properties by <a
href="https://github.com/jkoelker"><code>@​jkoelker</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/116">mark3labs/mcp-go#116</a></li>
<li>new feat: tool annotation by <a
href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/158">mark3labs/mcp-go#158</a></li>
<li>introduce NewToolResultErrorWithErr and update docs by <a
href="https://github.com/deviantony"><code>@​deviantony</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/140">mark3labs/mcp-go#140</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/tiborvass"><code>@​tiborvass</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/67">mark3labs/mcp-go#67</a></li>
<li><a href="https://github.com/leavez"><code>@​leavez</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/114">mark3labs/mcp-go#114</a></li>
<li><a
href="https://github.com/dugenkui03"><code>@​dugenkui03</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/158">mark3labs/mcp-go#158</a></li>
<li><a
href="https://github.com/deviantony"><code>@​deviantony</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/140">mark3labs/mcp-go#140</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.20.1...v0.21.0">https://github.com/mark3labs/mcp-go/compare/v0.20.1...v0.21.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/013c0472999e4cf5092a5c59966e081c0f8a9ea3"><code>013c047</code></a>
Use correct mutex</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/5378d0fc7d24957b72eb11d16eede5114c52c99e"><code>5378d0f</code></a>
feat: add message to ProgressNotification (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/119">#119</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/79a0ac0746186d1984f52a28ee2f7fac95ecbf53"><code>79a0ac0</code></a>
Add RemoveResource method to MCPServer (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/141">#141</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/0448984faa43f51a5c2da24b6ca7c6de392d025c"><code>0448984</code></a>
feat:Added the parameter parsing mode to parse any to the specified type
(<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/148">#148</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/dd3210c24230aa2b26c7cfb4f85fdce3197698f8"><code>dd3210c</code></a>
feat: Implement Streamable-HTTP Client Basic (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/168">#168</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/8c0f2be0e36beeac97644ea440f583cbbfe6772d"><code>8c0f2be</code></a>
feat(server): convert ping messages to be spec compliant (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/169">#169</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/d3c77dfa96811eb9de24087b4fedcbeba7782ac3"><code>d3c77df</code></a>
fix: add mutex to SSEServer to avoid data race between Start and
Shutdown; fi...</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/71b910bee8fee098e3412177dac8548453eee5c0"><code>71b910b</code></a>
fix: tool annotation (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/165">#165</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/37ac814a6010484d409bef15f6f4b015f486bdaa"><code>37ac814</code></a>
introduce NewToolResultErrorWithErr and update docs (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/140">#140</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/3fa49a8e7593122bc9a361214846a6e1e8f69116"><code>3fa49a8</code></a>
new feature: add tool annnotation (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/158">#158</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.20.1...v0.22.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.20.1&new-version=0.22.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 12:41:07 +00:00
dependabot[bot] b62335ea39 chore: bump github.com/moby/moby from 28.0.0+incompatible to 28.1.1+incompatible (#17477)
Bumps [github.com/moby/moby](https://github.com/moby/moby) from
28.0.0+incompatible to 28.1.1+incompatible.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/moby/moby/releases">github.com/moby/moby's
releases</a>.</em></p>
<blockquote>
<h2>v28.1.1</h2>
<h2>28.1.1</h2>
<p>For a full list of pull requests and changes in this release, refer
to the relevant GitHub milestones:</p>
<ul>
<li><a
href="https://github.com/docker/cli/issues?q=is%3Aclosed+milestone%3A28.1.1">docker/cli,
28.1.1 milestone</a></li>
<li><a
href="https://github.com/moby/moby/issues?q=is%3Aclosed+milestone%3A28.1.1">moby/moby,
28.1.1 milestone</a></li>
</ul>
<h3>Bug fixes and enhancements</h3>
<ul>
<li>Fix <code>dockerd-rootless-setuptool.sh</code> incorrectly reporting
missing <code>iptables</code>. <a
href="https://redirect.github.com/moby/moby/pull/49833">moby/moby#49833</a></li>
<li>containerd image store: Fix a potential daemon crash when using
<code>docker load</code> with archives containing zero-size tar headers.
<a
href="https://redirect.github.com/moby/moby/pull/49837">moby/moby#49837</a></li>
</ul>
<h3>Packaging updates</h3>
<ul>
<li>Update Buildx to <a
href="https://github.com/docker/buildx/releases/tag/v0.23.0">v0.23.0</a>.
<a
href="https://redirect.github.com/docker/docker-ce-packaging/pull/1185">docker/docker-ce-packaging#1185</a></li>
<li>Update Compose to <a
href="https://github.com/docker/compose/releases/tag/v2.35.1">v2.35.1</a>.
<a
href="https://redirect.github.com/docker/docker-ce-packaging/pull/1188">docker/docker-ce-packaging#1188</a></li>
</ul>
<h3>Networking</h3>
<ul>
<li>Add a warning to a container's <code>/etc/resolv.conf</code> when no
upstream DNS servers were found. <a
href="https://redirect.github.com/moby/moby/pull/49827">moby/moby#49827</a></li>
</ul>
<h2>v28.1.0</h2>
<h2>28.1.0</h2>
<p>For a full list of pull requests and changes in this release, refer
to the relevant GitHub milestones:</p>
<ul>
<li><a
href="https://github.com/docker/cli/issues?q=is%3Aclosed+milestone%3A28.1.0">docker/cli,
28.1.0 milestone</a></li>
<li><a
href="https://github.com/moby/moby/issues?q=is%3Aclosed+milestone%3A28.1.0">moby/moby,
28.1.0 milestone</a></li>
<li>Changes to the Engine API, see <a
href="https://github.com/moby/moby/blob/v28.1.0/docs/api/version-history.md">API
version history</a>.</li>
</ul>
<h3>New</h3>
<ul>
<li>Add <code>docker bake</code> sub-command as alias for <code>docker
buildx bake</code>. <a
href="https://redirect.github.com/docker/cli/pull/5947">docker/cli#5947</a></li>
<li>Experimental: add a new <code>--use-api-socket</code> flag on
<code>docker run</code> and <code>docker create</code> to enable access
to Docker socket from inside a container and to share credentials from
the host with the container. <a
href="https://redirect.github.com/docker/cli/pull/5858">docker/cli#5858</a></li>
<li><code>docker image inspect</code> now supports a
<code>--platform</code> flag to inspect a specific platform of a
multi-platform image. <a
href="https://redirect.github.com/docker/cli/pull/5934">docker/cli#5934</a></li>
</ul>
<h3>Bug fixes and enhancements</h3>
<ul>
<li>Add CLI shell-completion for context names. <a
href="https://redirect.github.com/docker/cli/pull/6016">docker/cli#6016</a></li>
<li>Fix <code>docker images --tree</code> not including non-container
images content size in the total image content size. <a
href="https://redirect.github.com/docker/cli/pull/6000">docker/cli#6000</a></li>
<li>Fix <code>docker load</code> not preserving replaced images. <a
href="https://redirect.github.com/moby/moby/pull/49650">moby/moby#49650</a></li>
<li>Fix <code>docker login</code> hints when logging in to a custom
registry. <a
href="https://redirect.github.com/docker/cli/pull/6015">docker/cli#6015</a></li>
<li>Fix <code>docker stats</code> not working properly on machines with
high CPU core count. <a
href="https://redirect.github.com/moby/moby/pull/49734">moby/moby#49734</a></li>
<li>Fix a regression causing <code>docker pull/push</code> to fail when
interacting with a private repository. <a
href="https://redirect.github.com/docker/cli/pull/5964">docker/cli#5964</a></li>
<li>Fix an issue preventing rootless Docker setup on a host with no
<code>ip_tables</code> kernel module. <a
href="https://redirect.github.com/moby/moby/pull/49727">moby/moby#49727</a></li>
<li>Fix an issue that could lead to unwanted iptables rules being
restored and never deleted following a firewalld reload. <a
href="https://redirect.github.com/moby/moby/pull/49728">moby/moby#49728</a></li>
<li>Improve CLI completion of <code>docker service scale</code>. <a
href="https://redirect.github.com/docker/cli/pull/5968">docker/cli#5968</a></li>
<li><code>docker images --tree</code> now hides both untagged and
dangling images by default. <a
href="https://redirect.github.com/docker/cli/pull/5924">docker/cli#5924</a></li>
<li><code>docker system info</code> will provide an exit code if a
connection cannot be established to the Docker daemon. <a
href="https://redirect.github.com/docker/cli/pull/5918">docker/cli#5918</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/moby/moby/commit/01f442b84d6a669c1e335b800d4670997cd5aa93"><code>01f442b</code></a>
Merge pull request <a
href="https://redirect.github.com/moby/moby/issues/49588">#49588</a>
from thaJeztah/bump_go_build_tags</li>
<li><a
href="https://github.com/moby/moby/commit/e03c0f03e7178cb4b9e927ffaeea73f228a7ad45"><code>e03c0f0</code></a>
Merge pull request <a
href="https://redirect.github.com/moby/moby/issues/49834">#49834</a>
from thaJeztah/cleanup_ignore</li>
<li><a
href="https://github.com/moby/moby/commit/8dde918e774b73971544b1e43586870e8e4acfeb"><code>8dde918</code></a>
Merge pull request <a
href="https://redirect.github.com/moby/moby/issues/49837">#49837</a>
from thaJeztah/bump_containerd_2.0.5</li>
<li><a
href="https://github.com/moby/moby/commit/e70ce7a35b94b0915dae5ba356a69d07ded2fd46"><code>e70ce7a</code></a>
Merge pull request <a
href="https://redirect.github.com/moby/moby/issues/49833">#49833</a>
from vvoland/rootless-iptables-check</li>
<li><a
href="https://github.com/moby/moby/commit/fc8361c0784a8a29347633d0b8f2280e57068078"><code>fc8361c</code></a>
vendor: github.com/containerd/containerd v2.0.5</li>
<li><a
href="https://github.com/moby/moby/commit/62f51e43670ffd1aa18672909cfa9e4300a2ab13"><code>62f51e4</code></a>
vendor: golang.org/x/oauth2 v0.29.0</li>
<li><a
href="https://github.com/moby/moby/commit/bbbb0036df25d56766bc5ce869080bdf0265e511"><code>bbbb003</code></a>
cleanup ignore files</li>
<li><a
href="https://github.com/moby/moby/commit/ead379a46457986eadf07273fedec378e87e515f"><code>ead379a</code></a>
contrib/rootless-setuptool: Fix iptables detection</li>
<li><a
href="https://github.com/moby/moby/commit/7c52c4d92e4fe584e2d25209a54c7d07c24baee1"><code>7c52c4d</code></a>
update go:build tags to go1.23 to align with vendor.mod</li>
<li><a
href="https://github.com/moby/moby/commit/6573a13e4adf5d9d3b2e0ab4e44ade244dd3c798"><code>6573a13</code></a>
Merge pull request <a
href="https://redirect.github.com/moby/moby/issues/49827">#49827</a>
from robmry/warn_no_ext_nameservers</li>
<li>Additional commits viewable in <a
href="https://github.com/moby/moby/compare/v28.0.0...v28.1.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/moby/moby&package-manager=go_modules&previous-version=28.0.0+incompatible&new-version=28.1.1+incompatible)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-21 12:17:43 +00:00
Spike Curtis 345435a04c feat: modify coordinators to send errors and peers to log them (#17467)
Adds support to our coordinator implementations to send Error updates before disconnecting clients.

I was recently debugging a connection issue where the client was getting repeatedly disconnected from the Coordinator, but since we never send any error information it was really hard without server logs.

This PR aims to correct that, by sending a CoordinateResponse with `Error` set in cases where we disconnect a client without them asking us to.

It also logs the error whenever we get one in the client controller.
2025-04-21 11:40:56 +04:00
Jaayden Halko ea017a1de8 feat: add textarea component and placeholders for dynamic parameters component (#17466)
- Hooks up the textarea component
- Adds placeholders for dropdown, input and multi-select combobox

---------

Co-authored-by: brettkolodny <brettkolodny@gmail.com>
2025-04-18 10:51:32 -04:00
Jaayden Halko 41b2165b47 feat: add textarea component (#17465)
This adds the shadcn textarea component along with storybook stories

Figma:
https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=1949-13239&t=NSt5S88hAsE4Q9di-1

<img width="612" alt="Screenshot 2025-04-18 at 12 16 57"
src="https://github.com/user-attachments/assets/dcd0281f-5d80-4047-9ba4-e456290ceb61"
/>
2025-04-18 10:43:07 -04:00
Ethan 6e0e29af13 chore: add agent query parameter to VSCodeDevContainerButton (#17464)
This is less work for the VSCode extension to do, and since the
workspace is running, we'll always know what agent to use.
2025-04-18 06:07:16 +00:00
ケイラ 03890aa904 chore: add jj to dogfood (#17434) 2025-04-17 16:08:51 -06:00
ケイラ 5f0ce7f543 fix: update url for parameters websocket endpoint (#17462) 2025-04-17 17:01:44 -05:00
ケイラ 2cc56ab515 chore: fill out workspace owner data for dynamic parameters (#17366) 2025-04-17 14:51:50 -06:00
Steven Masley ea65ddc17d fix: correct user roles being passed into terraform context (#17460)
Roles were being passed into the workspace context incorrectly. Site
wide scopes were being org scoped. Roles outside the org should also not
be sent.
2025-04-17 15:42:23 -05:00
Jaayden Halko 90eacc17de fix: fix issues with dynamic parameters in the state (#17459) 2025-04-17 16:16:08 -04:00
Yevhenii Shcherbina 183146e2c9 fix: add minor fix to reconciliation loop (#17454)
Follow-up PR to https://github.com/coder/coder/pull/17261
I noticed that 1 metrics-related test fails in `dk/prebuilds` after
merging my PR into `dk/prebuilds`.
2025-04-17 13:43:24 -04:00
ケイラ 144c60dd87 chore: upgrade fish to v4 (#17440) 2025-04-17 11:17:09 -06:00
Jaayden Halko 8723fe99f5 feat: add slider to dynamic parameters (#17453)
This adds the slider to the dynamic parameters component and does some
additional styling cleanup for the dynamic parameters form

<img width="630" alt="Screenshot 2025-04-17 at 16 54 05"
src="https://github.com/user-attachments/assets/1640e8df-7483-4275-99ee-682ff6218658"
/>
2025-04-17 12:40:37 -04:00
Bruno Quaresma 5e4050e529 chore: fix additional storybook flakes (#17450)
Fix new storybook flakes catch by
https://www.chromatic.com/test?appId=624de63c6aacee003aa84340&id=680107825818a9747e57236c
2025-04-17 11:08:13 -03:00
Bruno Quaresma c8edadae10 refactor: redesign workspace status on workspaces table (#17425)
Closes https://github.com/coder/coder/issues/17310

**Before:**
<img width="1624" alt="Screenshot 2025-04-16 at 11 49 52"
src="https://github.com/user-attachments/assets/4fb6c8e5-329f-476f-99bb-192c0f9562a2"
/>

**After:**
<img width="1624" alt="Screenshot 2025-04-16 at 11 49 19"
src="https://github.com/user-attachments/assets/c7025fee-fefd-4064-9101-d7a1b364dd80"
/>

**Notice!**
- I've create a new size variation for the badge, `xs`. Since we reduced
the line-height for the `text-xs` to be 16px instead of 18px, having a
smaller badge, reducing the vertical size and horizontal paddings, just
worked better.
- I have to update Figma to reflect these changes. I tried, but I was
not able to get it working and updated correctly. I'm going to take a
pause during this week to learn that.
- Updated the destructive, and warning badges to use borders as defined
in the designs
[here](https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=489-3472&t=gfnYeLOIFUqHx6qv-0).
2025-04-17 10:57:02 -03:00
Bruno Quaresma aa02c9ffb8 chore: reduce storybook flakes (#17427)
A few storybook tests have been false positives quite frequently. To
reduce this noise, I'm implementing a few hacks to avoid that. We can
always rollback these changes if we notice they were leading to a lack
in the tests.
2025-04-17 10:48:23 -03:00
Yevhenii Shcherbina 27bc60d1b9 feat: implement reconciliation loop (#17261)
Closes https://github.com/coder/internal/issues/510

<details>
<summary> Refactoring Summary </summary>

### 1) `CalculateActions` Function

#### Issues Before Refactoring:

- Large function (~150 lines), making it difficult to read and maintain.
- The control flow is hard to follow due to complex conditional logic.
- The `ReconciliationActions` struct was partially initialized early,
then mutated in multiple places, making the flow error-prone.

Original source:  

https://github.com/coder/coder/blob/fe60b569ad754245e28bac71e0ef3c83536631bb/coderd/prebuilds/state.go#L13-L167

#### Improvements After Refactoring:

- Simplified and broken down into smaller, focused helper methods.
- The flow of the function is now more linear and easier to understand.
- Struct initialization is cleaner, avoiding partial and incremental
mutations.

Refactored function:  

https://github.com/coder/coder/blob/eeb0407d783cdda71ec2418c113f325542c47b1c/coderd/prebuilds/state.go#L67-L84

---

### 2) `ReconciliationActions` Struct

#### Issues Before Refactoring:

- The struct mixed both actionable decisions and diagnostic state, which
blurred its purpose.
- It was unclear which fields were necessary for reconciliation logic,
and which were purely for logging/observability.

#### Improvements After Refactoring:

- Split into two clear, purpose-specific structs:
- **`ReconciliationActions`** — defines the intended reconciliation
action.
- **`ReconciliationState`** — captures runtime state and metadata,
primarily for logging and diagnostics.

Original struct:  

https://github.com/coder/coder/blob/fe60b569ad754245e28bac71e0ef3c83536631bb/coderd/prebuilds/reconcile.go#L29-L41

</details>

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Sas Swart <sas.swart.cdk@gmail.com>
Co-authored-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Dean Sheather <dean@deansheather.com>
Co-authored-by: Spike Curtis <spike@coder.com>
Co-authored-by: Danny Kopping <danny@coder.com>
2025-04-17 09:29:29 -04:00
Cian Johnston 6a79965948 fix(agent/agentcontainers): handle race between docker ps and docker inspect (#17447)
Fixes https://github.com/coder/internal/issues/586#event-17291038671
2025-04-17 13:50:51 +01:00
Spike Curtis b3aba6dab7 test: ignore context.Canceled in acquireWithCancel (#17448)
fixes https://github.com/coder/internal/issues/584

Ignore canceled error when sending an acquired job, since dRPC is racy and will sometimes return this error even after successfully sending the job, if the test is quickly finished.
2025-04-17 16:17:19 +04:00
Michael Suchacz daafa0d689 chore: add missing prometheus tests for UNKNOWN/STATIC paths (#17446) 2025-04-17 13:50:18 +02:00
Jaayden Halko 67a912796a feat: add slider component (#17431)
The slider component is part of the components supported by Dynamic
Parameters

There are no Figma designs for the slider component. This is based on
the shadcn slider.

<img width="474" alt="Screenshot 2025-04-16 at 19 26 11"
src="https://github.com/user-attachments/assets/87370a22-4984-48f7-875b-105568739003"
/>
2025-04-17 06:27:18 -04:00
Spike Curtis 9fe3fd4e28 chore: change config-ssh Call to Action to use suffix (#17445)
fixes #16828

With all the recent changes, I believe it is now safe to change the Call to Action for `config-ssh` to use the hostname suffix rather than prefix if it was set.
2025-04-17 12:16:29 +04:00
Spike Curtis b0854aa971 feat: modify config-ssh to check for Coder Connect (#17419)
relates to #16828

Changes SSH config so that suffixes only match if Coder Connect is not running / available. This means that we will use the existing Coder Connect tunnel if it is available, rather than creating a new tunnel via `coder ssh --stdio`.
2025-04-17 12:04:00 +04:00
Spike Curtis 3b54254177 feat: add coder connect exists hidden subcommand (#17418)
Adds a new hidden subcommand `coder connect exists <hostname>` that checks if the name exists via Coder Connect. This will be used in SSH config to match only if Coder Connect is unavailable for the hostname in question, so that the SSH client will directly dial the workspace over an existing Coder Connect tunnel.

Also refactors the way we inject a test DNS resolver into the lookup functions so that we can test from outside the `workspacesdk` package.
2025-04-17 11:23:24 +04:00
M Atif Ali 6f5da1e2ee chore: add windsurf icon (#17443) 2025-04-17 07:09:46 +00:00
Steven Masley 0bc49ff5ae test: fix flake in TestRoleSyncTable with test cases sharing resources (#17441)
The test case definition shares maps that can have concurrent access if run in parallel.
2025-04-17 00:14:11 +00:00
ケイラ 7f6e5139eb chore: format code (#17438) 2025-04-16 17:21:14 -06:00
Steven Masley 2e5cd299f2 chore: load 'assign_default' value from legacy value (#17428)
If this value was set before v2.19.0, then assign_default was in a json
field that would not match. And it would default to `false`. This
corrects that.
2025-04-16 15:55:37 -05:00
Steven Masley c4d3dd2791 chore: prevent null loading sync settings (#17430)
Nulls passed to the frontend caused a page to fail to load.

`Record<string,string>` can be `nil` in golang
2025-04-16 14:39:57 -05:00
Eric Paulsen d20966d500 chore: update go to 1.24.2 (#17356)
this updates `go` to the latest stable patch version `1.24.2` in:
- `go.mod`
- `dogfood/coder/Dockerfile`
- `.github/actions/setup-go/action.yaml`
- `flake.nix`

written with the assistance of ClaudeCode.

---------

Co-authored-by: Thomas Kosiewski <tk@coder.com>
2025-04-16 11:11:02 -07:00
Jaayden Halko a8c2586404 feat: implement UI for top level dynamic parameters diagnostics (#17394)
<img width="672" alt="Screenshot 2025-04-14 at 21 31 11"
src="https://github.com/user-attachments/assets/5ca25c9d-e82e-4d52-8c43-91e4dc31117d"
/>
2025-04-16 13:00:56 -04:00
Jaayden Halko 3d787da83b feat: setup connection to dynamic parameters websocket (#17393)
resolves coder/preview#57
2025-04-16 12:49:18 -04:00
ケイラ f670bc31f5 chore: update testutil chan helpers (#17408) 2025-04-16 10:37:09 -06:00
ケイラ 2a76f5028e fix: don't attempt to insert empty terraform plans into the database (#17426) 2025-04-16 10:14:35 -06:00
dependabot[bot] feb1a3dc02 chore: bump github.com/mark3labs/mcp-go from 0.17.0 to 0.20.0 (#17380)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.17.0 to 0.20.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.20.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: add ping for sse server by <a
href="https://github.com/lcgash"><code>@​lcgash</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/80">mark3labs/mcp-go#80</a></li>
<li>fix(client): allow interface to be implemented by <a
href="https://github.com/jkoelker"><code>@​jkoelker</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/135">mark3labs/mcp-go#135</a></li>
<li>feat: Tool Handler Middleware by <a
href="https://github.com/wimspaargaren"><code>@​wimspaargaren</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/123">mark3labs/mcp-go#123</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/lcgash"><code>@​lcgash</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/80">mark3labs/mcp-go#80</a></li>
<li><a href="https://github.com/jkoelker"><code>@​jkoelker</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/135">mark3labs/mcp-go#135</a></li>
<li><a
href="https://github.com/wimspaargaren"><code>@​wimspaargaren</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/123">mark3labs/mcp-go#123</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.19.0...v0.20.0">https://github.com/mark3labs/mcp-go/compare/v0.19.0...v0.20.0</a></p>
<h2>Release v0.19.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: SSE client hangs after 30 seconds by <a
href="https://github.com/mrene"><code>@​mrene</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/88">mark3labs/mcp-go#88</a></li>
<li>fix: change the default SSE endpoint to match the standard one used
in the official servers by <a
href="https://github.com/deadprogram"><code>@​deadprogram</code></a> in
<a
href="https://redirect.github.com/mark3labs/mcp-go/pull/91">mark3labs/mcp-go#91</a></li>
<li>fix: mcp-client should also include configurable http headers in the
/sse request by <a
href="https://github.com/kagezhao"><code>@​kagezhao</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/100">mark3labs/mcp-go#100</a></li>
<li>feat: use defer processing error by <a
href="https://github.com/songzhibin97"><code>@​songzhibin97</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/98">mark3labs/mcp-go#98</a></li>
<li>Feature/pagination functionality by <a
href="https://github.com/Jinlkj"><code>@​Jinlkj</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/107">mark3labs/mcp-go#107</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/mrene"><code>@​mrene</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/88">mark3labs/mcp-go#88</a></li>
<li><a
href="https://github.com/deadprogram"><code>@​deadprogram</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/91">mark3labs/mcp-go#91</a></li>
<li><a href="https://github.com/kagezhao"><code>@​kagezhao</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/100">mark3labs/mcp-go#100</a></li>
<li><a
href="https://github.com/songzhibin97"><code>@​songzhibin97</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/98">mark3labs/mcp-go#98</a></li>
<li><a href="https://github.com/Jinlkj"><code>@​Jinlkj</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/107">mark3labs/mcp-go#107</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.18.0...v0.19.0">https://github.com/mark3labs/mcp-go/compare/v0.18.0...v0.19.0</a></p>
<h2>Release v0.18.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: add NewToolResultError by <a
href="https://github.com/daimatz"><code>@​daimatz</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/87">mark3labs/mcp-go#87</a></li>
<li>refactor(stdio): improve stdio server message handling by <a
href="https://github.com/winterfx"><code>@​winterfx</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/73">mark3labs/mcp-go#73</a></li>
<li>Add Stderr() Method to StdioMCPClient by <a
href="https://github.com/mashiike"><code>@​mashiike</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/72">mark3labs/mcp-go#72</a></li>
<li>fix java mcp message endpoint by <a
href="https://github.com/a67793581"><code>@​a67793581</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/75">mark3labs/mcp-go#75</a></li>
<li>simplify required field handling in inputSchema by <a
href="https://github.com/yikakia"><code>@​yikakia</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/82">mark3labs/mcp-go#82</a></li>
<li>make context available in hooks, add OnRegisterSession hook by <a
href="https://github.com/zahmadsaleem"><code>@​zahmadsaleem</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/92">mark3labs/mcp-go#92</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/daimatz"><code>@​daimatz</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/87">mark3labs/mcp-go#87</a></li>
<li><a href="https://github.com/winterfx"><code>@​winterfx</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/73">mark3labs/mcp-go#73</a></li>
<li><a href="https://github.com/mashiike"><code>@​mashiike</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/72">mark3labs/mcp-go#72</a></li>
<li><a href="https://github.com/yikakia"><code>@​yikakia</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/82">mark3labs/mcp-go#82</a></li>
<li><a
href="https://github.com/zahmadsaleem"><code>@​zahmadsaleem</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/92">mark3labs/mcp-go#92</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.17.0...v0.18.0">https://github.com/mark3labs/mcp-go/compare/v0.17.0...v0.18.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/b8dc82de3e48d514d6ceac39aa5019064f437a53"><code>b8dc82d</code></a>
feat: Tool Handler Middleware (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/123">#123</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/6b923f677470564750cabbda1bb128912a735191"><code>6b923f6</code></a>
fix(client): allow interface to be implemented (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/135">#135</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/cc777fcbf3176d0e76634f58047707d1f666cae8"><code>cc777fc</code></a>
feat: add ping for sse server (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/80">#80</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/c7390feedf888e30cb29a1262a8827e3cd77b0e3"><code>c7390fe</code></a>
Feature/pagination functionality (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/107">#107</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/62cdf7131a59d291eb26f8172a4ecf1e8daefe7c"><code>62cdf71</code></a>
feat: use defer processing error (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/98">#98</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/1b7e34cc02be41251bdd4e6d5c2ccdfd0ba6f5d4"><code>1b7e34c</code></a>
mcp-client should also include configurable http headers in the /sse
request ...</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/d1e5f33feb16ee870198d462a4226e17a9eb57ce"><code>d1e5f33</code></a>
fix: make the default sse endpoint match the standard one used in the
officia...</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/f3149bfa6cc0b79e231f39214b76030ae0973409"><code>f3149bf</code></a>
fix: remove sse read timeout to avoid ignoring future sse messages (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/88">#88</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/a0e968a752722d87063eb36ea0d55938e752f6dd"><code>a0e968a</code></a>
feat: add context to hooks (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/92">#92</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/607d6c29bb8f56bc30e3154e99e58da1db78fcb9"><code>607d6c2</code></a>
simplify required field handling in inputSchema (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/82">#82</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.17.0...v0.20.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.17.0&new-version=0.20.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-16 14:56:12 +00:00
M Atif Ali 99979a78f5 docs: update jfrog-artifactory integration docs (#17413) 2025-04-16 19:48:26 +05:00
Steven Masley 669e790df6 test: add unit test to excercise bug when idp sync hits deleted orgs (#17405)
Deleted organizations are still attempting to sync members. This causes
an error on inserting the member, and would likely cause issues later in
the sync process even if that member is inserted. Deleted orgs should be
skipped.
2025-04-16 09:27:35 -05:00
Sas Swart 64172d374f fix: set preset parameters in the API rather than the frontend (#17403)
Follow-up from a [previous Pull
Request](https://github.com/coder/coder/pull/16965) required some
additional testing of Presets from the API perspective.

In the process of adding the new tests, I updated the API to enforce
preset parameter values based on the selected preset instead of trusting
whichever frontend makes the request. This avoids errors scenarios in
prebuilds where a prebuild might expect a certain preset but find a
different set of actual parameter values.
2025-04-16 15:54:06 +02:00
Borg93 d78215cdcb chore(site): add mlflow, lakefs and argo logos (#17332) 2025-04-16 11:25:02 +00:00
Spike Curtis b7cd545d0a test: fix TestConfigSSH_FileWriteAndOptionsFlow on Windows 11 24H2 (#17410)
Fixes tests on Windows 11 due to `printf` not being a recognized command name.
2025-04-16 14:29:45 +04:00
Aaron Lehmann 8cc743a812 chore: clarify error variable name in doAttach (#17284) 2025-04-16 14:44:33 +05:00
Michael Suchacz f8971bb3cc feat: add path & method labels to prometheus metrics for current requests (#17362)
Closes: #17212
2025-04-16 11:10:39 +02:00
Jaayden Halko 1db70bef5d feat: create dynamic parameter component (#17351)
- Create DynamicParameter component and test with locally run preview
websocket.
- Adapt CreateWorkspacePageExperimental to work with PreviewParameter
instead of TemplateVersionParameter
- Small changes to checkbox, multi-select combobox and radiogroup

The websocket implementation is temporary for testing purpose with a
locally run preview websocket
2025-04-16 05:00:25 -04:00
Steven Masley a7646d1524 chore: disable authz-header in all builds (#17409)
Header payload being large is causing some issues in dev builds. Another
method of opting in needs to be determined
2025-04-16 01:22:21 +00:00
brettkolodny 70b113de7b feat: add edit-role within user command (#17341) 2025-04-15 18:30:20 -04:00
Kyle Carberry 57ddb3c615 fix: update ai code prompt parameter in start-workspace.yaml 2025-04-15 15:15:00 -04:00
Kyle Carberry 362dcfefdd fix: update start-workspace.yaml for dev.coder.com (#17407)
I added the secrets and removed the aidev env secrets.
2025-04-15 15:10:30 -04:00
Edward Angert 0cd531dd33 docs: document workspace naming rules and restrictions (#17312)
closes #12047 


[preview](https://coder.com/docs/@12047-workspace-names/user-guides/workspace-management)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-15 14:11:05 -04:00
Bruno Quaresma b0fe626250 refactor: update the workspace table design (#17404)
Related to https://github.com/coder/coder/issues/17309

**Before:**
<img width="1624" alt="Screenshot 2025-04-15 at 11 36 32"
src="https://github.com/user-attachments/assets/ecca4c22-8d9c-4ee9-8c1d-193f538a0515"
/>

**After:**
<img width="1624" alt="Screenshot 2025-04-15 at 11 36 22"
src="https://github.com/user-attachments/assets/dd95b5cb-12c0-4806-8253-9be97d5a3a8a"
/>
2025-04-15 13:52:32 -03:00
Mathias Fredriksson 00b5f56734 feat(agent/agentcontainers): add devcontainers list endpoint (#17389)
This change allows listing both predefined and runtime-detected
devcontainers, as well as showing whether or not the devcontainer is
running and which container represents it.

Fixes coder/internal#478
2025-04-15 17:53:37 +03:00
Benjamin Peinhardt c8c4de5f7a chore(dogfood): add tmux (#17397) 2025-04-15 08:26:13 -05:00
Michael Suchacz 06d39151dc feat: extend request logs with auth & DB info (#17304)
Closes #16903
2025-04-15 13:27:23 +02:00
Cian Johnston 979687c37f chore(codersdk): deprecate WorkspaceAppStatus.{NeedsUserAttention,Icon} (#17358)
https://github.com/coder/coder/pull/17163 introduced the
`workspace_app_statuses` table. Two of these fields
(`needs_user_attention`, `icon`) turned out to be surplus to
requirements.

- Removes columns `needs_user_attention` and `icon` from
`workspace_app_statuses`
- Marks the corresponding fields of `codersdk.WorkspaceAppStatus` as
deprecated.
2025-04-15 10:47:42 +01:00
Danny Kopping 95f03c561f fix: increase context timeout in TestProvisionerd/MaliciousTar to avoid flake (#17400)
Fixing a flake seen here:
https://github.com/coder/coder/actions/runs/14465389766/job/40566518088

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-04-15 09:39:23 +00:00
Danny Kopping 0b18e458f4 fix: reduce excessive logging when database is unreachable (#17363)
Fixes #17045

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-04-15 10:55:30 +02:00
Hugo Dutka 2f99d70640 fix: configure start workspace action after version upgrade (#17398)
Dependabot recently upgraded `coder/start-workspace-action` to the
latest version. Compared to the version we were using previously, the
new version expects a different configuration.
2025-04-15 12:50:57 +05:00
dependabot[bot] fa594f4f6a ci: bump the github-actions group across 1 directory with 8 updates (#17377)
Bumps the github-actions group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
|
[step-security/harden-runner](https://github.com/step-security/harden-runner)
| `2.11.0` | `2.11.1` |
| [crate-ci/typos](https://github.com/crate-ci/typos) | `1.29.10` |
`1.31.1` |
| [actions/setup-java](https://github.com/actions/setup-java) | `4.7.0`
| `4.7.1` |
|
[tj-actions/changed-files](https://github.com/tj-actions/changed-files)
| `27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99` |
`9934ab3fdf63239da75d9e0fbd339c48620c72c4` |
| [tj-actions/branch-names](https://github.com/tj-actions/branch-names)
| `8.1.0` | `8.2.1` |
| [github/codeql-action](https://github.com/github/codeql-action) |
`3.28.12` | `3.28.15` |
|
[coder/start-workspace-action](https://github.com/coder/start-workspace-action)
| `26d3600161d67901f24d8612793d3b82771cde2d` |
`35a4608cefc7e8cc56573cae7c3b85304575cb72` |
|
[umbrelladocs/action-linkspector](https://github.com/umbrelladocs/action-linkspector)
| `1.3.2` | `1.3.4` |


Updates `step-security/harden-runner` from 2.11.0 to 2.11.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/step-security/harden-runner/releases">step-security/harden-runner's
releases</a>.</em></p>
<blockquote>
<h2>v2.11.1</h2>
<h2>What's Changed</h2>
<ul>
<li>cache: add support for GitHub Actions cache v2 by <a
href="https://github.com/h0x0er"><code>@​h0x0er</code></a> in <a
href="https://redirect.github.com/step-security/harden-runner/pull/529">step-security/harden-runner#529</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/step-security/harden-runner/compare/v2...v2.11.1">https://github.com/step-security/harden-runner/compare/v2...v2.11.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/step-security/harden-runner/commit/c6295a65d1254861815972266d5933fd6e532bdf"><code>c6295a6</code></a>
Merge pull request <a
href="https://redirect.github.com/step-security/harden-runner/issues/530">#530</a>
from step-security/rc-19</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/3e118b145bd13a08b2e465cf3a216df0f6c7746e"><code>3e118b1</code></a>
Improve error handling</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/b38e918ba8cf8d08113e53089af0d89429dcc51a"><code>b38e918</code></a>
Merge pull request <a
href="https://redirect.github.com/step-security/harden-runner/issues/529">#529</a>
from h0x0er/jatin/cache-fix</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/0664d30cda4109be234d326b54ac1cc6385597a2"><code>0664d30</code></a>
cache: added support for cache v2</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/b131ca5ebfca4930fe6d4a3e82d1e386b4873c94"><code>b131ca5</code></a>
Merge pull request <a
href="https://redirect.github.com/step-security/harden-runner/issues/524">#524</a>
from step-security/fix/security/GHSA-968p-4wvh-cqc8</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/2dc9579753e01c4033425fcc7b74e652b583ca50"><code>2dc9579</code></a>
Address vulnerabilities</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/f054d811b5b89fde2f954d54dc8622ec3aaab9ab"><code>f054d81</code></a>
Update README (<a
href="https://redirect.github.com/step-security/harden-runner/issues/522">#522</a>)</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/8a09271fed8277ab7fb02dbb5917c8d0e78323b4"><code>8a09271</code></a>
Update Readme (<a
href="https://redirect.github.com/step-security/harden-runner/issues/520">#520</a>)</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/6ec6af7d622602bd852df48848f3cae95c760a48"><code>6ec6af7</code></a>
Update readme (<a
href="https://redirect.github.com/step-security/harden-runner/issues/518">#518</a>)</li>
<li><a
href="https://github.com/step-security/harden-runner/commit/539365ba33fd040cf8c4db243b6f0ed3b32c3283"><code>539365b</code></a>
Merge pull request <a
href="https://redirect.github.com/step-security/harden-runner/issues/516">#516</a>
from vorburger/patch-1</li>
<li>Additional commits viewable in <a
href="https://github.com/step-security/harden-runner/compare/4d991eb9b905ef189e4c376166672c3f2f230481...c6295a65d1254861815972266d5933fd6e532bdf">compare
view</a></li>
</ul>
</details>
<br />

Updates `crate-ci/typos` from 1.29.10 to 1.31.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.31.1</h2>
<h2>[1.31.1] - 2025-03-31</h2>
<h3>Fixes</h3>
<ul>
<li><em>(dict)</em> Also correct <code>typ</code> to
<code>type</code></li>
</ul>
<h2>v1.31.0</h2>
<h2>[1.31.0] - 2025-03-28</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1266">March
2025</a> changes</li>
</ul>
<h2>v1.30.3</h2>
<h2>[1.30.3] - 2025-03-24</h2>
<h3>Features</h3>
<ul>
<li>Support detecting <code>go.work</code> and <code>go.work.sum</code>
files</li>
</ul>
<h2>v1.30.2</h2>
<h2>[1.30.2] - 2025-03-10</h2>
<h3>Features</h3>
<ul>
<li>Add <code>--highlight-words</code> and
<code>--highlight-identifiers</code> for easier debugging of config</li>
</ul>
<h2>v1.30.1</h2>
<h2>[1.30.1] - 2025-03-04</h2>
<h3>Features</h3>
<ul>
<li><em>(action)</em> Create <code>v1</code> tag</li>
</ul>
<h2>v1.30.0</h2>
<h2>[1.30.0] - 2025-03-01</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1221">February
2025</a> changes</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h1>Change Log</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>The format is based on <a href="http://keepachangelog.com/">Keep a
Changelog</a>
and this project adheres to <a href="http://semver.org/">Semantic
Versioning</a>.</p>
<!-- raw HTML omitted -->
<h2>[Unreleased] - ReleaseDate</h2>
<h2>[1.31.1] - 2025-03-31</h2>
<h3>Fixes</h3>
<ul>
<li><em>(dict)</em> Also correct <code>typ</code> to
<code>type</code></li>
</ul>
<h2>[1.31.0] - 2025-03-28</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1266">March
2025</a> changes</li>
</ul>
<h2>[1.30.3] - 2025-03-24</h2>
<h3>Features</h3>
<ul>
<li>Support detecting <code>go.work</code> and <code>go.work.sum</code>
files</li>
</ul>
<h2>[1.30.2] - 2025-03-10</h2>
<h3>Features</h3>
<ul>
<li>Add <code>--highlight-words</code> and
<code>--highlight-identifiers</code> for easier debugging of config</li>
</ul>
<h2>[1.30.1] - 2025-03-04</h2>
<h3>Features</h3>
<ul>
<li><em>(action)</em> Create <code>v1</code> tag</li>
</ul>
<h2>[1.30.0] - 2025-03-01</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1221">February
2025</a> changes</li>
</ul>
<h2>[1.29.10] - 2025-02-25</h2>
<h3>Fixes</h3>
<ul>
<li>Also correct <code>contaminent</code> as
<code>contaminant</code></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/crate-ci/typos/commit/b1a1ef3893ff35ade0cfa71523852a49bfd05d19"><code>b1a1ef3</code></a>
chore: Release</li>
<li><a
href="https://github.com/crate-ci/typos/commit/9c8a2c384f9b92ac5e7166040a1571141e271e7a"><code>9c8a2c3</code></a>
docs: Update changelog</li>
<li><a
href="https://github.com/crate-ci/typos/commit/12195d75fea9498ad83cb8d85e357a986e90fb7e"><code>12195d7</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1267">#1267</a>
from epage/type</li>
<li><a
href="https://github.com/crate-ci/typos/commit/d4dbe5f77bde37609ce3424df4a713a61f87ad2b"><code>d4dbe5f</code></a>
fix(dict): Also correct typ to type</li>
<li><a
href="https://github.com/crate-ci/typos/commit/718c4ff697435edabd4f1c52c3775521adbb33a3"><code>718c4ff</code></a>
chore: Release</li>
<li><a
href="https://github.com/crate-ci/typos/commit/bfbf137ed65f9abe0e9a3a92a354a787ca084240"><code>bfbf137</code></a>
chore: Release</li>
<li><a
href="https://github.com/crate-ci/typos/commit/d47e90e4ffad8924461124c3b3787e220b811956"><code>d47e90e</code></a>
docs: Update changelog</li>
<li><a
href="https://github.com/crate-ci/typos/commit/0694c2a98227bebeefdfff96f2086480295d00a5"><code>0694c2a</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1266">#1266</a>
from epage/march</li>
<li><a
href="https://github.com/crate-ci/typos/commit/f715ca8b0824515b13e3e51ed80c8a255d8a7d07"><code>f715ca8</code></a>
feat(dict): March 2025 updates</li>
<li><a
href="https://github.com/crate-ci/typos/commit/d08e4083f112e684fb88f6babd9ae60a1f1cd84f"><code>d08e408</code></a>
chore: Release</li>
<li>Additional commits viewable in <a
href="https://github.com/crate-ci/typos/compare/db35ee91e80fbb447f33b0e5fbddb24d2a1a884f...b1a1ef3893ff35ade0cfa71523852a49bfd05d19">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/setup-java` from 4.7.0 to 4.7.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-java/releases">actions/setup-java's
releases</a>.</em></p>
<blockquote>
<h2>v4.7.1</h2>
<h2>What's Changed</h2>
<h3>Documentation changes</h3>
<ul>
<li>Add Documentation to Recommend Using GraalVM JDK 17 Version to
17.0.12 to Align with GFTC License Terms by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-java/pull/704">actions/setup-java#704</a></li>
<li>Remove duplicated GraalVM section in documentation by <a
href="https://github.com/Marcono1234"><code>@​Marcono1234</code></a> in
<a
href="https://redirect.github.com/actions/setup-java/pull/716">actions/setup-java#716</a></li>
</ul>
<h3>Dependency updates:</h3>
<ul>
<li>Upgrade <code>@​action/cache</code> from 4.0.0 to 4.0.2 by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-java/pull/766">actions/setup-java#766</a></li>
<li>Upgrade <code>@​actions/glob</code> from 0.4.0 to 0.5.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-java/pull/744">actions/setup-java#744</a></li>
<li>Upgrade ts-jest from 29.1.2 to 29.2.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/setup-java/pull/743">actions/setup-java#743</a></li>
<li>Upgrade <code>@​action/cache</code> to 4.0.3 by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://redirect.github.com/actions/setup-java/pull/773">actions/setup-java#773</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-java/compare/v4...v4.7.1">https://github.com/actions/setup-java/compare/v4...v4.7.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/setup-java/commit/c5195efecf7bdfc987ee8bae7a71cb8b11521c00"><code>c5195ef</code></a>
actions/cache upgrade to 4.0.3 (<a
href="https://redirect.github.com/actions/setup-java/issues/773">#773</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/dd38875f930accc291b5816356a21f72056c0b70"><code>dd38875</code></a>
Bump ts-jest from 29.1.2 to 29.2.5 (<a
href="https://redirect.github.com/actions/setup-java/issues/743">#743</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/148017a9b0c6af80330bcc5db11d1c670d2e7074"><code>148017a</code></a>
Bump <code>@​actions/glob</code> from 0.4.0 to 0.5.0 (<a
href="https://redirect.github.com/actions/setup-java/issues/744">#744</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/3b6c050358614dd082e53cdbc55580431fc4e437"><code>3b6c050</code></a>
Remove duplicated GraalVM section in documentation (<a
href="https://redirect.github.com/actions/setup-java/issues/716">#716</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/b8ebb8ba1d9655f7f159c0a8b8135606ae11b5c9"><code>b8ebb8b</code></a>
upgrade <code>@​action/cache</code> from 4.0.0 to 4.0.2 (<a
href="https://redirect.github.com/actions/setup-java/issues/766">#766</a>)</li>
<li><a
href="https://github.com/actions/setup-java/commit/799ee7c97e9721ef38d1a7e8486c39753b9d6102"><code>799ee7c</code></a>
Add Documentation to Recommend Using GraalVM JDK 17 Version to 17.0.12
to Ali...</li>
<li>See full diff in <a
href="https://github.com/actions/setup-java/compare/3a4f6e1af504cf6a31855fa899c6aa5355ba6c12...c5195efecf7bdfc987ee8bae7a71cb8b11521c00">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/changed-files` from
27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99 to
9934ab3fdf63239da75d9e0fbd339c48620c72c4
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/changed-files/blob/main/HISTORY.md">tj-actions/changed-files's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.4...v46.0.5">46.0.5</a>
- (2025-04-09)</h1>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li><strong>deps:</strong> Bump yaml from 2.7.0 to 2.7.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2520">#2520</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/ed68ef82c095e0d48ec87eccea555d944a631a4c">ed68ef8</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump typescript from 5.8.2 to 5.8.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2516">#2516</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/a7bc14b808f23d3b467a4079c69a81f1a4500fd5">a7bc14b</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump <code>@​types/node</code> from
22.13.11 to 22.14.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2517">#2517</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/3d751f6b6d84071a17e1b9cf4ed79a80a27dd0ab">3d751f6</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump eslint-plugin-prettier from 5.2.3 to
5.2.6 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2519">#2519</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/e2fda4ec3cb0bc2a353843cae823430b3124db8f">e2fda4e</a>)
- (dependabot[bot])</li>
<li><strong>deps-dev:</strong> Bump ts-jest from 29.2.6 to 29.3.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2518">#2518</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/0bed1b1132ec4879a39a2d624cf82a00d0bcfa48">0bed1b1</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump github/codeql-action from 3.28.12 to
3.28.15 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2530">#2530</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/68024587dc36f49685c96d59d3f1081830f968bb">6802458</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/branch-names from 8.0.1 to
8.1.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2521">#2521</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/cf2e39e86bf842d1f9bc5bca56c0a6b207cca792">cf2e39e</a>)
- (dependabot[bot])</li>
<li><strong>deps:</strong> Bump tj-actions/verify-changed-files from
20.0.1 to 20.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2523">#2523</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6abeaa506a419f85fa9e681260b443adbeebb3d4">6abeaa5</a>)
- (dependabot[bot])</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.4 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2511">#2511</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/6f67ee9ac810f0192ea7b3d2086406f97847bcf9">6f67ee9</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.3...v46.0.4">46.0.4</a>
- (2025-04-03)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li>Bug modified_keys and changed_key outputs not set when no changes
detected (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2509">#2509</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/6cb76d07bee4c9772c6882c06c37837bf82a04d3">6cb76d0</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<ul>
<li>Update readme (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2508">#2508</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/b74df86ccb65173a8e33ba5492ac1a2ca6b216fd">b74df86</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2506">#2506</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted -->
Co-authored-by: Tonye Jack <a
href="mailto:jtonye@ymail.com">jtonye@ymail.com</a> (<a
href="https://github.com/tj-actions/changed-files/commit/27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99">27ae6b3</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.2...v46.0.3">46.0.3</a>
- (2025-03-23)</h1>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2501">#2501</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/41e0de576a0f2b64d9f06f2773f539109e55a70a">41e0de5</a>)
- (github-actions[bot])</p>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2499">#2499</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/945787811a795cd840a1157ac590dd7827a05c8e">9457878</a>)
- (github-actions[bot])</p>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/changed-files/commit/9934ab3fdf63239da75d9e0fbd339c48620c72c4"><code>9934ab3</code></a>
chore(deps-dev): bump eslint-config-prettier from 10.1.1 to 10.1.2 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2532">#2532</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/db731a131ccd81ed52a3d463b6d2a4b2856c7ec9"><code>db731a1</code></a>
Upgraded to v46.0.5 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2531">#2531</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/ed68ef82c095e0d48ec87eccea555d944a631a4c"><code>ed68ef8</code></a>
chore(deps): bump yaml from 2.7.0 to 2.7.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2520">#2520</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/a7bc14b808f23d3b467a4079c69a81f1a4500fd5"><code>a7bc14b</code></a>
chore(deps-dev): bump typescript from 5.8.2 to 5.8.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2516">#2516</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/3d751f6b6d84071a17e1b9cf4ed79a80a27dd0ab"><code>3d751f6</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.13.11 to 22.14.0
(<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2517">#2517</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/e2fda4ec3cb0bc2a353843cae823430b3124db8f"><code>e2fda4e</code></a>
chore(deps-dev): bump eslint-plugin-prettier from 5.2.3 to 5.2.6 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2519">#2519</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/0bed1b1132ec4879a39a2d624cf82a00d0bcfa48"><code>0bed1b1</code></a>
chore(deps-dev): bump ts-jest from 29.2.6 to 29.3.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2518">#2518</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/68024587dc36f49685c96d59d3f1081830f968bb"><code>6802458</code></a>
chore(deps): bump github/codeql-action from 3.28.12 to 3.28.15 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2530">#2530</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/cf2e39e86bf842d1f9bc5bca56c0a6b207cca792"><code>cf2e39e</code></a>
chore(deps): bump tj-actions/branch-names from 8.0.1 to 8.1.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2521">#2521</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/6abeaa506a419f85fa9e681260b443adbeebb3d4"><code>6abeaa5</code></a>
chore(deps): bump tj-actions/verify-changed-files from 20.0.1 to 20.0.4
(<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2523">#2523</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tj-actions/changed-files/compare/27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99...9934ab3fdf63239da75d9e0fbd339c48620c72c4">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/branch-names` from 8.1.0 to 8.2.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/branch-names/releases">tj-actions/branch-names's
releases</a>.</em></p>
<blockquote>
<h2>v8.2.1</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: update sync-release-version.yml to sign commits by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/416">tj-actions/branch-names#416</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/tj-actions/branch-names/compare/v8.2.0...v8.2.1">https://github.com/tj-actions/branch-names/compare/v8.2.0...v8.2.1</a></p>
<h2>v8.2.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Upgraded to v8.1.0 by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/410">tj-actions/branch-names#410</a></li>
<li>feat: add support for replace forward slashes with hyphens by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/412">tj-actions/branch-names#412</a></li>
<li>chore: update update-readme.yml by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/414">tj-actions/branch-names#414</a></li>
<li>Updated README.md by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>
in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/415">tj-actions/branch-names#415</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/github-actions"><code>@​github-actions</code></a>
made their first contribution in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/415">tj-actions/branch-names#415</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/tj-actions/branch-names/compare/v8...v8.2.0">https://github.com/tj-actions/branch-names/compare/v8...v8.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/branch-names/blob/main/HISTORY.md">tj-actions/branch-names's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/branch-names/compare/v8.2.0...v8.2.1">8.2.1</a>
- (2025-04-11)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li>Update sync-release-version.yml to sign commits (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/416">#416</a>)
(<a
href="https://github.com/tj-actions/branch-names/commit/dde14ac574a8b9b1cedc59a1cf312788af43d8d8">dde14ac</a>)
- (Tonye Jack)</li>
</ul>
<h1><a
href="https://github.com/tj-actions/branch-names/compare/v8.1.0...v8.2.0">8.2.0</a>
- (2025-04-11)</h1>
<h2><!-- raw HTML omitted -->🚀 Features</h2>
<ul>
<li>Add support for replace forward slashes with hyphens (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/412">#412</a>)
(<a
href="https://github.com/tj-actions/branch-names/commit/af406356b42c0855d5d112babee4a0b76ee630df">af40635</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted --> Remove</h2>
<ul>
<li>Deleted .github/workflows/rebase.yml (<a
href="https://github.com/tj-actions/branch-names/commit/c209967c9a91450d7dced6e5adc3c61ca030c868">c209967</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/415">#415</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/branch-names/commit/47dfecabcf7a70329c1d7fc49d56ce56739c5420">47dfeca</a>)
- (github-actions[bot])</p>
<ul>
<li>Update update-readme.yml (<a
href="https://github.com/tj-actions/branch-names/commit/c9cf6f9a0e21d41fb9acf4025894c022a1dd22db">c9cf6f9</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li>Update update-readme.yml (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/414">#414</a>)
(<a
href="https://github.com/tj-actions/branch-names/commit/b1f61bc147718240eda9ab8a823f836416ab297c">b1f61bc</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded from v8.0.2 -&gt; v8.1.0 (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/410">#410</a>)</li>
</ul>
<p>(<a
href="https://github.com/tj-actions/branch-names/commit/96012203a066021edaf47a9381953d843444eacf">9601220</a>)
- (Tonye Jack)</p>
<h1><a
href="https://github.com/tj-actions/branch-names/compare/v8.0.2...v8.1.0">8.1.0</a>
- (2025-03-23)</h1>
<h2><!-- raw HTML omitted -->🚀 Features</h2>
<ul>
<li>Add support for strip_branch_prefix (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/406">#406</a>)
(<a
href="https://github.com/tj-actions/branch-names/commit/c83c87ab5379a8ff88c905ea78c391c0d53972ac">c83c87a</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/408">#408</a>)</li>
</ul>
<p>(<a
href="https://github.com/tj-actions/branch-names/commit/d18e657ed32f367301fdebeb9a88b7e5539f3052">d18e657</a>)
- (Tonye Jack)</p>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li>Update test.yml (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/409">#409</a>)
(<a
href="https://github.com/tj-actions/branch-names/commit/f44339b51f74753b57583fbbd124e18a81170ab1">f44339b</a>)
- (Tonye Jack)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/branch-names/commit/dde14ac574a8b9b1cedc59a1cf312788af43d8d8"><code>dde14ac</code></a>
fix: update sync-release-version.yml to sign commits (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/416">#416</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/47dfecabcf7a70329c1d7fc49d56ce56739c5420"><code>47dfeca</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/415">#415</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/c9cf6f9a0e21d41fb9acf4025894c022a1dd22db"><code>c9cf6f9</code></a>
Update update-readme.yml</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/b1f61bc147718240eda9ab8a823f836416ab297c"><code>b1f61bc</code></a>
chore: update update-readme.yml (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/414">#414</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/af406356b42c0855d5d112babee4a0b76ee630df"><code>af40635</code></a>
feat: add support for replace forward slashes with hyphens (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/412">#412</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/c209967c9a91450d7dced6e5adc3c61ca030c868"><code>c209967</code></a>
Deleted .github/workflows/rebase.yml</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/96012203a066021edaf47a9381953d843444eacf"><code>9601220</code></a>
Upgraded from v8.0.2 -&gt; v8.1.0 (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/410">#410</a>)</li>
<li>See full diff in <a
href="https://github.com/tj-actions/branch-names/compare/f44339b51f74753b57583fbbd124e18a81170ab1...dde14ac574a8b9b1cedc59a1cf312788af43d8d8">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action` from 3.28.12 to 3.28.15
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.28.15</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.15 - 07 Apr 2025</h2>
<ul>
<li>Fix bug where the action would fail if it tried to produce a debug
artifact with more than 65535 files. <a
href="https://redirect.github.com/github/codeql-action/pull/2842">#2842</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.15/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
<h2>v3.28.14</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.14 - 07 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.0. <a
href="https://redirect.github.com/github/codeql-action/pull/2838">#2838</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.14/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
<h2>v3.28.13</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.13 - 24 Mar 2025</h2>
<p>No user facing changes.</p>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.13/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.28.15 - 07 Apr 2025</h2>
<ul>
<li>Fix bug where the action would fail if it tried to produce a debug
artifact with more than 65535 files. <a
href="https://redirect.github.com/github/codeql-action/pull/2842">#2842</a></li>
</ul>
<h2>3.28.14 - 07 Apr 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.21.0. <a
href="https://redirect.github.com/github/codeql-action/pull/2838">#2838</a></li>
</ul>
<h2>3.28.13 - 24 Mar 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.12 - 19 Mar 2025</h2>
<ul>
<li>Dependency caching should now cache more dependencies for Java
<code>build-mode: none</code> extractions. This should speed up
workflows and avoid inconsistent alerts in some cases.</li>
<li>Update default CodeQL bundle version to 2.20.7. <a
href="https://redirect.github.com/github/codeql-action/pull/2810">#2810</a></li>
</ul>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<h2>3.28.10 - 21 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.5. <a
href="https://redirect.github.com/github/codeql-action/pull/2772">#2772</a></li>
<li>Address an issue where the CodeQL Bundle would occasionally fail to
decompress on macOS. <a
href="https://redirect.github.com/github/codeql-action/pull/2768">#2768</a></li>
</ul>
<h2>3.28.9 - 07 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.4. <a
href="https://redirect.github.com/github/codeql-action/pull/2753">#2753</a></li>
</ul>
<h2>3.28.8 - 29 Jan 2025</h2>
<ul>
<li>Enable support for Kotlin 2.1.10 when running with CodeQL CLI
v2.20.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2744">#2744</a></li>
</ul>
<h2>3.28.7 - 29 Jan 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.6 - 27 Jan 2025</h2>
<ul>
<li>Re-enable debug artifact upload for CLI versions 2.20.3 or greater.
<a
href="https://redirect.github.com/github/codeql-action/pull/2726">#2726</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/45775bd8235c68ba998cffa5171334d58593da47"><code>45775bd</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2854">#2854</a>
from github/update-v3.28.15-a35ae8c38</li>
<li><a
href="https://github.com/github/codeql-action/commit/dd78aab4078b17a672a66d6a80a990beb672ede1"><code>dd78aab</code></a>
Update CHANGELOG.md with bug fix details</li>
<li><a
href="https://github.com/github/codeql-action/commit/e40af591743761de70080085b4e6ce37f7f6e657"><code>e40af59</code></a>
Update changelog for v3.28.15</li>
<li><a
href="https://github.com/github/codeql-action/commit/a35ae8c380fa35365cd546f9a397a46f60dd82cf"><code>a35ae8c</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2843">#2843</a>
from github/cklin/diff-informed-compat</li>
<li><a
href="https://github.com/github/codeql-action/commit/bb59df6c174a91d88eec1c48f2ab0ef7b5f96e99"><code>bb59df6</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2842">#2842</a>
from github/henrymercer/zip64</li>
<li><a
href="https://github.com/github/codeql-action/commit/4b508f59648bef88ef72c74f1ffff531fda55ea8"><code>4b508f5</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2845">#2845</a>
from github/mergeback/v3.28.14-to-main-fc7e4a0f</li>
<li><a
href="https://github.com/github/codeql-action/commit/ca00afb5f1457cf1c85da6cda07d73e720ff061a"><code>ca00afb</code></a>
Update checked-in dependencies</li>
<li><a
href="https://github.com/github/codeql-action/commit/2969c78ce0262bf75658058604498d2b4bdb0b9b"><code>2969c78</code></a>
Update changelog and version after v3.28.14</li>
<li><a
href="https://github.com/github/codeql-action/commit/fc7e4a0fa01c3cca5fd6a1fddec5c0740c977aa2"><code>fc7e4a0</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2844">#2844</a>
from github/update-v3.28.14-362ef4ce2</li>
<li><a
href="https://github.com/github/codeql-action/commit/be0175c800fe14dd962aaa2c97f55371f6f95b35"><code>be0175c</code></a>
Update changelog for v3.28.14</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/5f8171a638ada777af81d42b55959a643bb29017...45775bd8235c68ba998cffa5171334d58593da47">compare
view</a></li>
</ul>
</details>
<br />

Updates `coder/start-workspace-action` from
26d3600161d67901f24d8612793d3b82771cde2d to
35a4608cefc7e8cc56573cae7c3b85304575cb72
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/coder/start-workspace-action/commit/35a4608cefc7e8cc56573cae7c3b85304575cb72"><code>35a4608</code></a>
update <code>github-username</code> description to specify requirement
for Coder 2.21 or...</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/0054568c043bba479899edb91ef96a5cfca21c55"><code>0054568</code></a>
clarify requirements for the <code>github-username</code> input</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/f3cda2e65a469e6dd60478c111c745b919c0ec68"><code>f3cda2e</code></a>
fix variable names</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/a6a41dc1eb63a8e58dc43a97a2c2cb04ccc40b36"><code>a6a41dc</code></a>
update readme</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/a09e31de35a1d153448ed707d63708e2a2acef3c"><code>a09e31d</code></a>
more defaults for inputs</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/13304209b2b4449befcb6d0392693311aad1faff"><code>1330420</code></a>
Add a screenshot to the README</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/8d0b0d4118b6fa0c504b79c06dc99f4ed024c749"><code>8d0b0d4</code></a>
clarify status comment</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/747b408cb53f6e3440ba04f951c75077994ff95a"><code>747b408</code></a>
update input descriptions</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/e526e6fb8e781ffacf59c6066194286a9f3cee8a"><code>e526e6f</code></a>
update example action tag</li>
<li><a
href="https://github.com/coder/start-workspace-action/commit/212ab2f68a115ca64029be34610433cfa16a89e0"><code>212ab2f</code></a>
update readme and add a license</li>
<li>Additional commits viewable in <a
href="https://github.com/coder/start-workspace-action/compare/26d3600161d67901f24d8612793d3b82771cde2d...35a4608cefc7e8cc56573cae7c3b85304575cb72">compare
view</a></li>
</ul>
</details>
<br />

Updates `umbrelladocs/action-linkspector` from 1.3.2 to 1.3.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/umbrelladocs/action-linkspector/releases">umbrelladocs/action-linkspector's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.3.4</h2>
<p>v1.3.4: PR <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/42">#42</a>
- Update linkspector version to 0.4.4</p>
<h2>Release v1.3.3</h2>
<p>v1.3.3: PR <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/41">#41</a>
- Update linkspector version to 0.4.3</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/a0567ce1c7c13de4a2358587492ed43cab5d0102"><code>a0567ce</code></a>
Merge pull request <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/42">#42</a>
from UmbrellaDocs/update-linkspector-version</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/f5418fddbc33d4b79076fee4e41451501c6ceb0f"><code>f5418fd</code></a>
Update linkspector version to 0.4.4</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/3e12ade1e0b1823455dae8cf8b4f9cc92ec7dd20"><code>3e12ade</code></a>
Merge pull request <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/41">#41</a>
from UmbrellaDocs/update-linkspector-version</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/8dfab6548de1b83b975ac3262626c2d1875f59f1"><code>8dfab65</code></a>
Update linkspector version to 0.4.3</li>
<li>See full diff in <a
href="https://github.com/umbrelladocs/action-linkspector/compare/49cf4f8da82db70e691bb8284053add5028fa244...a0567ce1c7c13de4a2358587492ed43cab5d0102">compare
view</a></li>
</ul>
</details>
<br />

<details>
<summary>Most Recent Ignore Conditions Applied to This Pull
Request</summary>

| Dependency Name | Ignore Conditions |
| --- | --- |
| crate-ci/typos | [>= 1.30.a, < 1.31] |
</details>


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Muhammad Atif Ali <atif@coder.com>
2025-04-14 19:55:01 +00:00
M Atif Ali e54aa442eb chore(dogfood): switch to JetBrains Toolbox module (#17392) 2025-04-14 21:34:52 +05:00
Cian Johnston 272edba1d8 feat(codersdk/toolsdk): add template_version_id to coder_create_workspace_build (#17364)
The `coder_create_workspace_build` tool was missing the ability to
change the template version.
2025-04-14 17:29:43 +01:00
Cian Johnston 2d2c9bda98 fix(cli): correct logic around CODER_MCP_APP_STATUS_SLUG (#17391)
Past me was not smart.
2025-04-14 16:24:02 +01:00
Sas Swart a98605913a feat: mark prebuilds as such and set their preset ids (#16965)
This pull request closes https://github.com/coder/internal/issues/513
2025-04-14 15:34:50 +02:00
Spike Curtis 73f5af82ad test: fix TestAgent_Lifecycle/ShutdownScriptOnce to wait for stats (#17387)
fixes: https://github.com/coder/internal/issues/576

TestAgent_Lifecycle/ShutdownScriptOnce hits error logs which cause test
failures. These logs are legit errors and have to do with shutting down
the agent before it has fully come up.

This PR changes the test to wait for the agent to send stats (a good
indicator that it's fully up, and beyond the errors that have triggered
test failures in past) before closing it.
2025-04-14 12:20:50 +00:00
Spike Curtis d8fcb062bc chore: add logging for coderdtest server lifecycle (#17376)
regarding https://github.com/coder/internal/issues/581

Adds logging around the lifecyle of the coderd HTTP server.
2025-04-14 16:15:06 +04:00
Edward Angert 34752fa148 docs: add note about sign in with GitHub button should be hidden when flow is disabled (#17367)
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-14 17:03:25 +05:00
dependabot[bot] 1c040edec4 chore: bump vite from 5.4.17 to 5.4.18 in /site (#17385)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite)
from 5.4.17 to 5.4.18.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v5.4.18</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v5.4.18/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/v5.4.18/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted -->5.4.18 (2025-04-10)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19830">#19830</a>,
reject requests with <code>#</code> in request-target (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19831">#19831</a>)
(<a
href="https://github.com/vitejs/vite/commit/823675baff2bd6809c74ba2d9acca0327923a54f">823675b</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19830">#19830</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/19831">#19831</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/731b77d19d36f5682a5441b49cb2f6473389ad99"><code>731b77d</code></a>
release: v5.4.18</li>
<li><a
href="https://github.com/vitejs/vite/commit/823675baff2bd6809c74ba2d9acca0327923a54f"><code>823675b</code></a>
fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19830">#19830</a>,
reject requests with <code>#</code> in request-target (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19831">#19831</a>)</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite/commits/v5.4.18/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vite&package-manager=npm_and_yarn&previous-version=5.4.17&new-version=5.4.18)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 12:02:26 +00:00
dependabot[bot] f75d01fd58 chore: bump github.com/gohugoio/hugo from 0.143.0 to 0.146.3 (#17384)
Bumps [github.com/gohugoio/hugo](https://github.com/gohugoio/hugo) from
0.143.0 to 0.146.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/gohugoio/hugo/releases">github.com/gohugoio/hugo's
releases</a>.</em></p>
<blockquote>
<h2>v0.146.3</h2>
<h2>What's Changed</h2>
<ul>
<li>tpl: Make any layout set in front matter higher priority 30b9c19c7
<a href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13588">#13588</a></li>
<li>tpl: Fix it so embedded render-codeblock-goat is used even if custom
render-codeblock exists c8710625b <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13595">#13595</a></li>
</ul>
<h2>v0.146.2</h2>
<h2>What's Changed</h2>
<ul>
<li>tpl: Fix codeblock hook resolve issue d1c394442 <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13593">#13593</a></li>
<li>tpl: Fix legacy section mappings 1074e0115 <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13584">#13584</a></li>
<li>tpl: Resolve layouts/all.html for all html output formats c19f1f236
<a href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13587">#13587</a></li>
<li>tpl: Fix some baseof lookup issues 9221cbca4 <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13583">#13583</a></li>
</ul>
<h2>v0.146.1</h2>
<p>This fixes a regression introduced in <a
href="https://github.com/gohugoio/hugo/releases/tag/v0.146.0">v0.146.0</a>
released earlier today.</p>
<ul>
<li>tpl: Skip dot and temp files inside /layouts 3b9f2a7de <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13579">#13579</a></li>
</ul>
<h2>v0.146.0</h2>
<blockquote>
<p>[!NOTE]
There's a <a
href="https://github.com/gohugoio/hugo/releases/tag/v0.146.1">v0.146.1</a>
bug fix release that fixes a regression introduced in this release.</p>
</blockquote>
<p>The big new thing in this release is a fully refreshed template
system – simpler and much better. We're working on the updated
documentation for this, but see <a
href="https://redirect.github.com/gohugoio/hugo/pull/13541">this
issue</a> for some more information. We have gone to great lengths to
make this as backwards compatible as possible, but make sure you test
your site before going live with this new version. This version also
comes with a full dependency refresh and some useful new template
funcs:</p>
<ul>
<li><a
href="https://gohugo.io/functions/templates/current/">templates.Current</a>:
Info about the current executing template and its call stack. Very
useful for debugging.</li>
<li><a href="https://gohugo.io/functions/time/in/">time.In</a>: Returns
the given date/time as represented in the specified IANA time zone.</li>
</ul>
<h2>Bug fixes</h2>
<ul>
<li>tpl/tplimpl: Fix full screen option in vimeo and youtube shortcodes
6f14dbe24 <a
href="https://github.com/jmooring"><code>@​jmooring</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13531">#13531</a></li>
</ul>
<h2>Improvements</h2>
<ul>
<li>tpl: Warn and skip non-hook templates inside /layouts/_markup
383dd82f9 <a href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13577">#13577</a></li>
<li>tpl: Add a partial lookup cache 208a0de6c <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13571">#13571</a></li>
<li>tpl: Add templates.Current d4c6dd16b <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13571">#13571</a></li>
<li>commands/new: Improve theme creation 24ac6a9de <a
href="https://github.com/jmooring"><code>@​jmooring</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13489">#13489</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/13544">#13544</a></li>
<li>tpl/tplimpl: Update embedded pagination template 1e0084248 <a
href="https://github.com/jmooring"><code>@​jmooring</code></a></li>
<li>Reimplement and simplify Hugo's template system 83cfdd78c <a
href="https://github.com/bep"><code>@​bep</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13541">#13541</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/13545">#13545</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/13515">#13515</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/7964">#7964</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/13365">#13365</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/12988">#12988</a>
<a
href="https://redirect.github.com/gohugoio/hugo/issues/4891">#4891</a></li>
<li>config: Use the non-global logger for deprecations when possible
812ea0b32 <a href="https://github.com/bep"><code>@​bep</code></a></li>
<li>tpl/time: Add time.In function 07cbe5701 <a
href="https://github.com/jmooring"><code>@​jmooring</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13548">#13548</a></li>
<li>resources: Add option to silence dependency deprecation warnings
c15ebce2f <a
href="https://github.com/jmooring"><code>@​jmooring</code></a> <a
href="https://redirect.github.com/gohugoio/hugo/issues/13530">#13530</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/gohugoio/hugo/commit/05ef8b713a3c091bfca7a3543ed016c64b3c6f88"><code>05ef8b7</code></a>
releaser: Bump versions for release of 0.146.3</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/30b9c19c7691aa3d90854c92a355bd8a248bb5b0"><code>30b9c19</code></a>
tpl: Make any layout set in front matter higher priority</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/c8710625b7c01a0d580f9d896b1fea96ec5463d1"><code>c871062</code></a>
tpl: Fix it so embedded render-codeblock-goat is used even if custom
render-c...</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/53221f88ca57634b1b8afeeeacdc923e25b6617c"><code>53221f8</code></a>
releaser: Prepare repository for 0.147.0-DEV</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/ff3ab192c27fccdd82393f223040874904a44e98"><code>ff3ab19</code></a>
releaser: Bump versions for release of 0.146.2</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/d1c394442be0858b12fb1dbb42a98237e95c6d75"><code>d1c3944</code></a>
tpl: Fix codeblock hook resolve issue</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/1074e011520a82a17524d2e68082e5a04e291c2a"><code>1074e01</code></a>
tpl: Fix legacy section mappings</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/c19f1f2363fe96cfa8b6e4a5b9e5d75886bcff8b"><code>c19f1f2</code></a>
tpl: Resolve layouts/all.html for all html output formats</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/9221cbca496752fb1d06d664871e3d4532f473f5"><code>9221cbc</code></a>
tpl: Fix some baseof lookup issues</li>
<li><a
href="https://github.com/gohugoio/hugo/commit/e3e3f9ae17395220e2c13ddc8afa7000a5a7e21e"><code>e3e3f9a</code></a>
releaser: Prepare repository for 0.147.0-DEV</li>
<li>Additional commits viewable in <a
href="https://github.com/gohugoio/hugo/compare/v0.143.0...v0.146.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/gohugoio/hugo&package-manager=go_modules&previous-version=0.143.0&new-version=0.146.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 11:54:47 +00:00
dependabot[bot] 06d707d865 chore: bump github.com/prometheus/client_golang from 1.21.1 to 1.22.0 (#17382)
Bumps
[github.com/prometheus/client_golang](https://github.com/prometheus/client_golang)
from 1.21.1 to 1.22.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prometheus/client_golang/releases">github.com/prometheus/client_golang's
releases</a>.</em></p>
<blockquote>
<h2>v1.22.0 - 2025-04-07</h2>
<p>⚠️ This release contains potential breaking change if you use
experimental <code>zstd</code> support introduce in <a
href="https://redirect.github.com/prometheus/client_golang/issues/1496">#1496</a>
⚠️</p>
<p>Experimental support for <code>zstd</code> on scrape was added,
controlled by the request <code>Accept-Encoding</code> header.
It was enabled by default since version 1.20, but now you need to add a
blank import to enable it.
The decision to make it opt-in by default was originally made because
the Go standard library was expected to have default zstd support added
soon,
<a
href="https://redirect.github.com/golang/go/issues/62513">golang/go#62513</a>
however, the work took longer than anticipated and it will be postponed
to upcoming major Go versions.</p>
<p>e.g.:</p>
<blockquote>
<pre lang="go"><code>import (
_
&quot;github.com/prometheus/client_golang/prometheus/promhttp/zstd&quot;
)
</code></pre>
</blockquote>
<ul>
<li>[FEATURE] prometheus: Add new CollectorFunc utility <a
href="https://redirect.github.com/prometheus/client_golang/issues/1724">#1724</a></li>
<li>[CHANGE] Minimum required Go version is now 1.22 (we also test
client_golang against latest go version - 1.24) <a
href="https://redirect.github.com/prometheus/client_golang/issues/1738">#1738</a></li>
<li>[FEATURE] api: <code>WithLookbackDelta</code> and
<code>WithStats</code> options have been added to API client. <a
href="https://redirect.github.com/prometheus/client_golang/issues/1743">#1743</a></li>
<li>[CHANGE] ⚠️ promhttp: Isolate zstd support and
klauspost/compress library use to promhttp/zstd package. <a
href="https://redirect.github.com/prometheus/client_golang/issues/1765">#1765</a></li>
</ul>
<!-- raw HTML omitted -->
<ul>
<li>build(deps): bump golang.org/x/sys from 0.28.0 to 0.29.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1720">prometheus/client_golang#1720</a></li>
<li>build(deps): bump google.golang.org/protobuf from 1.36.1 to 1.36.3
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1719">prometheus/client_golang#1719</a></li>
<li>Update RELEASE.md by <a
href="https://github.com/bwplotka"><code>@​bwplotka</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1721">prometheus/client_golang#1721</a></li>
<li>chore(docs): Add links for the upstream PRs by <a
href="https://github.com/kakkoyun"><code>@​kakkoyun</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1722">prometheus/client_golang#1722</a></li>
<li>Added tips on releasing client and checking with k8s. by <a
href="https://github.com/bwplotka"><code>@​bwplotka</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1723">prometheus/client_golang#1723</a></li>
<li>feat: Add new CollectorFunc utility by <a
href="https://github.com/Saumya40-codes"><code>@​Saumya40-codes</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1724">prometheus/client_golang#1724</a></li>
<li>build(deps): bump google.golang.org/protobuf from 1.36.3 to 1.36.4
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1725">prometheus/client_golang#1725</a></li>
<li>build(deps): bump the github-actions group with 5 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1726">prometheus/client_golang#1726</a></li>
<li>Synchronize common files from prometheus/prometheus by <a
href="https://github.com/prombot"><code>@​prombot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1727">prometheus/client_golang#1727</a></li>
<li>Synchronize common files from prometheus/prometheus by <a
href="https://github.com/prombot"><code>@​prombot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1731">prometheus/client_golang#1731</a></li>
<li>build(deps): bump golang.org/x/sys from 0.29.0 to 0.30.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1739">prometheus/client_golang#1739</a></li>
<li>build(deps): bump google.golang.org/protobuf from 1.36.4 to 1.36.5
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1740">prometheus/client_golang#1740</a></li>
<li>Cleanup dependabot config by <a
href="https://github.com/SuperQ"><code>@​SuperQ</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1741">prometheus/client_golang#1741</a></li>
<li>Upgrade Golang version v1.24 by <a
href="https://github.com/dongjiang1989"><code>@​dongjiang1989</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1738">prometheus/client_golang#1738</a></li>
<li>build(deps): bump the github-actions group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1742">prometheus/client_golang#1742</a></li>
<li>Merging 1.21 release back to main. by <a
href="https://github.com/bwplotka"><code>@​bwplotka</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1744">prometheus/client_golang#1744</a></li>
<li>Synchronize common files from prometheus/prometheus by <a
href="https://github.com/prombot"><code>@​prombot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1745">prometheus/client_golang#1745</a></li>
<li>Add support for undocumented query options for API by <a
href="https://github.com/mahendrapaipuri"><code>@​mahendrapaipuri</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1743">prometheus/client_golang#1743</a></li>
<li>exp/api: Add experimental exp module; Add remote API with write
client and handler. by <a
href="https://github.com/bwplotka"><code>@​bwplotka</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1658">prometheus/client_golang#1658</a></li>
<li>exp/api: Add accepted msg type validation to handler by <a
href="https://github.com/saswatamcode"><code>@​saswatamcode</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1750">prometheus/client_golang#1750</a></li>
<li>build(deps): bump the github-actions group with 5 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1751">prometheus/client_golang#1751</a></li>
<li>build(deps): bump github.com/klauspost/compress from 1.17.11 to
1.18.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1752">prometheus/client_golang#1752</a></li>
<li>build(deps): bump github.com/google/go-cmp from 0.6.0 to 0.7.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1753">prometheus/client_golang#1753</a></li>
<li>exp: Reset snappy buf by <a
href="https://github.com/saswatamcode"><code>@​saswatamcode</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1756">prometheus/client_golang#1756</a></li>
<li>Merge release 1.21.1 to main. by <a
href="https://github.com/bwplotka"><code>@​bwplotka</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1762">prometheus/client_golang#1762</a></li>
<li>exp: Add dependabot config by <a
href="https://github.com/saswatamcode"><code>@​saswatamcode</code></a>
in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1754">prometheus/client_golang#1754</a></li>
<li>build(deps): bump peter-evans/create-pull-request from 7.0.7 to
7.0.8 in the github-actions group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/client_golang/pull/1764">prometheus/client_golang#1764</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md">github.com/prometheus/client_golang's
changelog</a>.</em></p>
<blockquote>
<h2>1.22.0 / 2025-04-07</h2>
<p>⚠️ This release contains potential breaking change if you use
experimental <code>zstd</code> support introduce in <a
href="https://redirect.github.com/prometheus/client_golang/issues/1496">#1496</a>
⚠️</p>
<p>Experimental support for <code>zstd</code> on scrape was added,
controlled by the request <code>Accept-Encoding</code> header.
It was enabled by default since version 1.20, but now you need to add a
blank import to enable it.
The decision to make it opt-in by default was originally made because
the Go standard library was expected to have default zstd support added
soon,
<a
href="https://redirect.github.com/golang/go/issues/62513">golang/go#62513</a>
however, the work took longer than anticipated and it will be postponed
to upcoming major Go versions.</p>
<p>e.g.:</p>
<blockquote>
<pre lang="go"><code>import (
_
&quot;github.com/prometheus/client_golang/prometheus/promhttp/zstd&quot;
)
</code></pre>
</blockquote>
<ul>
<li>[FEATURE] prometheus: Add new CollectorFunc utility <a
href="https://redirect.github.com/prometheus/client_golang/issues/1724">#1724</a></li>
<li>[CHANGE] Minimum required Go version is now 1.22 (we also test
client_golang against latest go version - 1.24) <a
href="https://redirect.github.com/prometheus/client_golang/issues/1738">#1738</a></li>
<li>[FEATURE] api: <code>WithLookbackDelta</code> and
<code>WithStats</code> options have been added to API client. <a
href="https://redirect.github.com/prometheus/client_golang/issues/1743">#1743</a></li>
<li>[CHANGE] ⚠️ promhttp: Isolate zstd support and
klauspost/compress library use to promhttp/zstd package. <a
href="https://redirect.github.com/prometheus/client_golang/issues/1765">#1765</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/prometheus/client_golang/commit/d50be25511d790f4c166d68ce7d046c2977d148b"><code>d50be25</code></a>
Cut 1.22.0 (<a
href="https://redirect.github.com/prometheus/client_golang/issues/1793">#1793</a>)</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/1043db7cb8735186b341bbff6ae45d7ff56018dd"><code>1043db7</code></a>
Cut 1.22.0-rc.0 (<a
href="https://redirect.github.com/prometheus/client_golang/issues/1768">#1768</a>)</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/e575c9c04e40fe0784d4fee7f1f56c1a66ef090d"><code>e575c9c</code></a>
promhttp: Isolate zstd support and klauspost/compress library use to
promhttp...</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/f2276aa7d4b6e6526e0011762d0e4070513cf9cd"><code>f2276aa</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus/client_golang/issues/1764">#1764</a>
from prometheus/dependabot/github_actions/github-act...</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/9df772cc5f399a2946a9158e57fd0aff66daf7d1"><code>9df772c</code></a>
build(deps): bump peter-evans/create-pull-request</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/a3548c5aa811a0a52d1d723c3dfb3b01930481fb"><code>a3548c5</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus/client_golang/issues/1754">#1754</a>
from saswatamcode/exp-eh</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/60fd2b0490db6e7c74e623651031feae93c7ebc1"><code>60fd2b0</code></a>
Remove go.work file for now</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/8f9d0de6893dd7a470cdb1cffc5d98d1b5d7b50d"><code>8f9d0de</code></a>
exp: Add dependabot config</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/c5cf981312d510414c209927e4f9e888d6776b5c"><code>c5cf981</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus/client_golang/issues/1762">#1762</a>
from prometheus/release-1.21</li>
<li><a
href="https://github.com/prometheus/client_golang/commit/e84c30512a658de7fdccce84b434c9a5696ec5af"><code>e84c305</code></a>
exp: Reset snappy buf (<a
href="https://redirect.github.com/prometheus/client_golang/issues/1756">#1756</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/prometheus/client_golang/compare/v1.21.1...v1.22.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/prometheus/client_golang&package-manager=go_modules&previous-version=1.21.1&new-version=1.22.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 11:54:29 +00:00
dependabot[bot] b6ff6b160a chore: bump github.com/charmbracelet/bubbles from 0.20.0 to 0.21.0 (#17381)
Bumps
[github.com/charmbracelet/bubbles](https://github.com/charmbracelet/bubbles)
from 0.20.0 to 0.21.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/charmbracelet/bubbles/releases">github.com/charmbracelet/bubbles's
releases</a>.</em></p>
<blockquote>
<h2>v0.21.0</h2>
<h2>Viewport improvements</h2>
<p>Finally, <code>viewport</code> finally has <em>horizontal
scrolling</em> ![^v1]
To enable it, use <code>SetHorizontalStep</code> (default in v2 will be
<code>6</code>).</p>
<p>You can also scroll manually with <code>ScrollLeft</code> and
<code>ScrollRight</code>, and use
<code>SetXOffset</code> to scroll to a specific position (or
<code>0</code> to reset):</p>
<pre lang="go"><code>vp := viewport.New()
vp.SetHorizontalStep(10) // how many columns to scroll on each key press
vp.ScrollRight(30)       // pan 30 columns to the right!
vp.ScrollLeft(10)        // pan 10 columns to the left!
vp.SetXOffset(0)         // back to the left edge
</code></pre>
<p>To make the API more consistent, vertical scroll functions were also
renamed,
and the old ones were deprecated (and will be removed in v2):</p>
<pre lang="go"><code>// Scroll n lines up/down:
func (m Model) LineUp(int)     // deprecated
func (m Model) ScrollUp(int)   // new!
func (m Model) LineDown(int)   // deprecated
func (m Model) ScrollDown(int) // new!
<p>// Scroll half page up/down:
func (m Model) HalfViewUp() []string   // deprecated
func (m Model) HalfPageUp() []string   // new!
func (m Model) HalfViewDown() []string // deprecated
func (m Model) HalfPageDown() []string // new!</p>
<p>// Scroll a full page up/down:
func (m Model) ViewUp(int) []string   // deprecated
func (m Model) PageUp(int) []string   // new!
func (m Model) ViewDown(int) []string // deprecated
func (m Model) PageDown(int) []string // new!
</code></pre></p>
<blockquote>
<p>[!NOTE]
In v2, these functions will not return <code>lines []string</code>
anymore, as it is no
longer needed due to <code>HighPerformanceRendering</code> being
deprecated as well.</p>
</blockquote>
<h2>Other improvements</h2>
<p>The <code>list</code> bubble got a couple of new functions:
<code>SetFilterText</code>,
<code>SetFilterState</code>, and <code>GlobalIndex</code> - which you
can use to get the index of the
item in the unfiltered, original item list.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/8b55efb2944ed8eb81df685f8dcfabbbf8897698"><code>8b55efb</code></a>
fix(textarea): placeholder with chinese chars (<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/767">#767</a>)</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/bd2a5b0c6a7abc66b8a009d2aded233e6ba02fa4"><code>bd2a5b0</code></a>
fix: golangci-lint 2 fixes (<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/769">#769</a>)</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/cce848148cbea9e1bc5ca7d2c3d1ef89702db0e4"><code>cce8481</code></a>
ci: sync golangci-lint config (<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/770">#770</a>)</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/ea344ab907bddf5e8f71cd73b9583b070e8f1b2f"><code>ea344ab</code></a>
feat(viewport): horizontal scroll with mouse wheel (<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/761">#761</a>)</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/39668ec6291e1fc3e574f30c650e1ba0801e1f6d"><code>39668ec</code></a>
fix(viewport): normalize method names (<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/763">#763</a>)</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/f2434c374bd0f55ac0d5b3e8261161b97ea41a30"><code>f2434c3</code></a>
Revert &quot;fix(viewport): normalize method names&quot;</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/c7f889e364e15dc5b08a8c799e80164031847ab9"><code>c7f889e</code></a>
fix(viewport): normalize method names</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/9e5365e0ec0c4005efc7a3cc47f67941840e4144"><code>9e5365e</code></a>
docs: add example for ValidateFunc (<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/705">#705</a>)</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/c814ac75c3b4be111bf163c07655971543be33f9"><code>c814ac7</code></a>
chore(deps): bump github.com/charmbracelet/lipgloss from 1.0.0 to 1.1.0
(<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/751">#751</a>)</li>
<li><a
href="https://github.com/charmbracelet/bubbles/commit/3befcccf8702cb29ad196acc10b4899aa16b47f0"><code>3befccc</code></a>
chore(deps): bump github.com/muesli/termenv from 0.15.2 to 0.16.0 (<a
href="https://redirect.github.com/charmbracelet/bubbles/issues/740">#740</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/charmbracelet/bubbles/compare/v0.20.0...v0.21.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/charmbracelet/bubbles&package-manager=go_modules&previous-version=0.20.0&new-version=0.21.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 11:53:56 +00:00
dependabot[bot] 199c408dd9 chore: bump the x group with 2 updates (#17379)
Bumps the x group with 2 updates:
[golang.org/x/net](https://github.com/golang/net) and
[golang.org/x/tools](https://github.com/golang/tools).

Updates `golang.org/x/net` from 0.38.0 to 0.39.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/net/commit/b8d88774daf2a7cf137dad5173fc9bb981fc18fb"><code>b8d8877</code></a>
go.mod: update golang.org/x dependencies</li>
<li>See full diff in <a
href="https://github.com/golang/net/compare/v0.38.0...v0.39.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/tools` from 0.31.0 to 0.32.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/tools/commit/456962ef0d65798b244374a272fb19b7d9723b62"><code>456962e</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="https://github.com/golang/tools/commit/5916e3cbd8b65f73c18253607fa0b696fc5b9da6"><code>5916e3c</code></a>
internal/tokeninternal: AddExistingFiles: tweaks for proposal</li>
<li><a
href="https://github.com/golang/tools/commit/9a1fbbdb530258f2c0db9c411aecf399d1ec256b"><code>9a1fbbd</code></a>
internal/typesinternal: change Used to UsedIdent</li>
<li><a
href="https://github.com/golang/tools/commit/e73cd5af773602fdbc6cab94bdc0dc38abf828ab"><code>e73cd5a</code></a>
gopls/internal/golang: implement dynamicFuncCallType with
typeutil.ClassifyCall</li>
<li><a
href="https://github.com/golang/tools/commit/11a9b3f89dc9e5a2e6d738d243258495a9c53005"><code>11a9b3f</code></a>
gopls/internal/server: fix event labels after the big rename</li>
<li><a
href="https://github.com/golang/tools/commit/3e7f74d009150bf5e66483f3759d8c59f50e873d"><code>3e7f74d</code></a>
go/types/typeutil: used doesn't need Info.Selections</li>
<li><a
href="https://github.com/golang/tools/commit/b97074b9c8ebe7cce7db7be133120bc966f9c33f"><code>b97074b</code></a>
internal/gofix: fix URLs</li>
<li><a
href="https://github.com/golang/tools/commit/e850fe1872cee508a221a3efd67dd2901deddc4c"><code>e850fe1</code></a>
gopls/internal/golang: CodeAction: place gopls doc as the last
action</li>
<li><a
href="https://github.com/golang/tools/commit/b948add7e7e4926ce52fb3a01e15c18e4558c252"><code>b948add</code></a>
internal/gofix: move from gopls/internal/analysis/gofix</li>
<li><a
href="https://github.com/golang/tools/commit/b437eff8291cf46efe66e499f4c0ac5c8df770d5"><code>b437eff</code></a>
go/types/typeutil: implement Callee and StaticCallee with Used</li>
<li>Additional commits viewable in <a
href="https://github.com/golang/tools/compare/v0.31.0...v0.32.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 11:53:37 +00:00
dependabot[bot] e2ebc9d549 chore: bump github.com/go-jose/go-jose/v4 from 4.0.5 to 4.1.0 (#17383)
Bumps
[github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from
4.0.5 to 4.1.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/go-jose/go-jose/releases">github.com/go-jose/go-jose/v4's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Document <code>signatureAlgorithms</code> argument by <a
href="https://github.com/tgeoghegan"><code>@​tgeoghegan</code></a> in <a
href="https://redirect.github.com/go-jose/go-jose/pull/163">go-jose/go-jose#163</a></li>
<li>Add custom error for unsupported JWS signature algorithms by <a
href="https://github.com/beautifulentropy"><code>@​beautifulentropy</code></a>
in <a
href="https://redirect.github.com/go-jose/go-jose/pull/181">go-jose/go-jose#181</a></li>
<li>use stdlib pbkdf2 package on go 1.24 by <a
href="https://github.com/kruskall"><code>@​kruskall</code></a> in <a
href="https://redirect.github.com/go-jose/go-jose/pull/180">go-jose/go-jose#180</a></li>
<li>The minimum supported Go version is now 1.24</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/kruskall"><code>@​kruskall</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-jose/go-jose/pull/180">go-jose/go-jose#180</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/go-jose/go-jose/compare/v4.0.5...v4.1.0">https://github.com/go-jose/go-jose/compare/v4.0.5...v4.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/go-jose/go-jose/commit/4f005daa10d11cacd7376358a5fe5d0c1c0ee487"><code>4f005da</code></a>
Add changelog entry for <a
href="https://redirect.github.com/go-jose/go-jose/issues/181">#181</a>
(<a
href="https://redirect.github.com/go-jose/go-jose/issues/183">#183</a>)</li>
<li><a
href="https://github.com/go-jose/go-jose/commit/fed5f4a89ce20a6c826bf3d6871c47c22b280178"><code>fed5f4a</code></a>
feat: use stdlib pbkdf2 package on go 1.24 (<a
href="https://redirect.github.com/go-jose/go-jose/issues/180">#180</a>)</li>
<li><a
href="https://github.com/go-jose/go-jose/commit/6e50d10239d754e5544fcc28b79b78b87a177a4c"><code>6e50d10</code></a>
Add custom error for unsupported JWS signature algorithms (<a
href="https://redirect.github.com/go-jose/go-jose/issues/181">#181</a>)</li>
<li><a
href="https://github.com/go-jose/go-jose/commit/0e4ab6846ac17cad0096f6391736270a5c4f630f"><code>0e4ab68</code></a>
Bump CI Go to 1.23.x and 1.24.x (<a
href="https://redirect.github.com/go-jose/go-jose/issues/177">#177</a>)</li>
<li><a
href="https://github.com/go-jose/go-jose/commit/9dc538453357899787e4695857167e75f1c16745"><code>9dc5384</code></a>
Document <code>signatureAlgorithms</code> argument (<a
href="https://redirect.github.com/go-jose/go-jose/issues/163">#163</a>)</li>
<li><a
href="https://github.com/go-jose/go-jose/commit/783e3f5b2d4b8c3c3fd19e739306cb9db1ced8bc"><code>783e3f5</code></a>
Bump github.com/google/go-cmp from 0.6.0 to 0.7.0 (<a
href="https://redirect.github.com/go-jose/go-jose/issues/165">#165</a>)</li>
<li>See full diff in <a
href="https://github.com/go-jose/go-jose/compare/v4.0.5...v4.1.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-jose/go-jose/v4&package-manager=go_modules&previous-version=4.0.5&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 11:53:27 +00:00
Spike Curtis e5ce3824ca feat: add IsCoderConnectRunning to workspacesdk (#17361)
Adds `IsCoderConnectRunning()` to the workspacesdk. This will support the `coder` CLI being able to use CoderConnect when it's running.

part of #16828
2025-04-14 09:47:46 +04:00
Steven Masley 39b9d23d96 chore: remove nullable list elements in ts typegen (#17369)
Backend will not send partially null slices.
2025-04-11 15:49:18 -05:00
Jon Ayers c06ef7c1eb chore!: remove JFrog integration (#17353)
- Removes displaying XRay scan results in the dashboard. I'm not sure
  anyone was even using this integration so it's just debt for us to
  maintain. We can open up a separate issue to get rid of the db tables
  once we know for sure that we haven't broken anyone.
2025-04-11 14:45:21 -04:00
Steven Masley 15584e69ef chore: fixup typegen for preview types (#17339)
Preview types override the json marshal behavior.
2025-04-11 13:21:46 -05:00
Cian Johnston 7b0422b49b fix(codersdk/toolsdk): fix tool schemata (#17365)
Fixes two issues with the MCP server:
- Ensures we have a non-null schema, as the following schema was making
claude-code unhappy:

 
```
        "inputSchema": { "type": "object", "properties": null },
```


- Skip adding the coder_report_task tool if an agent client is not
available. Otherwise the agent may try to report tasks and get confused.
2025-04-11 18:58:17 +01:00
Edward Angert 6330b0d545 docs: add steps to pre-install JetBrains IDE backend (#15962)
closes #13207 


[preview](https://coder.com/docs/@13207-preinstall-jetbrains/user-guides/workspace-access/jetbrains)

---------

Co-authored-by: M Atif Ali <atif@coder.com>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-11 11:55:04 -04:00
Jaayden Halko 6a6e1ec50c feat: add support for icons and warning variant in Badge component (#17350)
<img width="172" alt="Screenshot 2025-04-10 at 23 11 32"
src="https://github.com/user-attachments/assets/2556feb1-bf49-4044-90fd-6ac15582c258"
/>
2025-04-11 10:16:37 -04:00
Spike Curtis 9e2af3e127 feat: add configurable DNS match domain for tailnet connections (#17336)
Use the hostname suffix to set the DNS match domain when creating a Tailnet as part of the vpn `Tunnel`.

part of: #16828
2025-04-11 15:00:48 +04:00
Spike Curtis 69aa365169 fix: remove provisioner/terraform/testdata/resources/version.txt (#17357)
Removes `provisioner/terraform/testdata/resources/version.txt`

Pretty sure Claude hallucinated it into existence in #17035 based on the similar `provisioner/terraform/testdata/version.txt`
2025-04-11 14:46:32 +04:00
Cian Johnston 1235550637 feat(codersdk): add toolsdk and replace existing mcp server tool impl (#17343)
- Refactors existing `mcp` package to use `kylecarbs/aisdk-go` and moves
to `codersdk/toolsdk` package.
- Updates existing MCP server implementation to use `codersdk/toolsdk`

Co-authored-by: Kyle Carberry <kyle@coder.com>
2025-04-11 10:24:45 +01:00
Spike Curtis 2c573dc023 feat: vpn uses WorkspaceHostnameSuffix for DNS names (#17335)
Use the hostname suffix to set DNS names as programmed into the DNS service and returned by the vpn `Tunnel`.

part of: #16828
2025-04-11 13:24:20 +04:00
Spike Curtis 12dc086628 feat: return hostname suffix on AgentConnectionInfo (#17334)
Adds the Hostname Suffix to `AgentConnectionInfo` --- the VPN provider will use it to control the suffix for DNS hostnames.

part of: #16828
2025-04-11 13:09:51 +04:00
Mathias Fredriksson 60fbe675ed refactor(agent/agentcontainers): implement API service (#17340)
This refactor improves separation of API and containers with minimal
changes to logic.

Highlights:

- Routes are now defined in `agentcontainers` package
- Handler renamed to API
- API lazy init was moved into NewAPI
- Tests that don't need to be internal were made external
2025-04-11 11:41:13 +03:00
Ethan 7bca3e237a chore: update tailscale (#17327)
Relates to https://github.com/coder/internal/issues/466

Brings in https://github.com/coder/tailscale/pull/70
2025-04-11 14:03:00 +10:00
Ethan 3c1cb5d05a chore: add generic DNS record for checking if Coder Connect is running (#17298)
Closes https://github.com/coder/internal/issues/466

```
$ dig -6 @fd60:627a:a42b::53 is.coder--connect--enabled--right--now.coder AAAA

; <<>> DiG 9.10.6 <<>> -6 @fd60:627a:a42b::53 is.coder--connect--enabled--right--now.coder AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62390
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;is.coder--connect--enabled--right--now.coder. IN AAAA

;; ANSWER SECTION:
is.coder--connect--enabled--right--now.coder. 2	IN AAAA	fd60:627a:a42b::53

;; Query time: 3 msec
;; SERVER: fd60:627a:a42b::53#53(fd60:627a:a42b::53)
;; WHEN: Wed Apr 09 16:59:18 AEST 2025
;; MSG SIZE  rcvd: 134
```

Hostname considerations:
- Workspace names, usernames, and agent names can't have double hyphens, so this name can't conflict with a real Coder Connect hostname.
- Components can't start or end with hyphens according to [RFC 952](https://www.rfc-editor.org/rfc/rfc952.html)
- DNS records can't have hyphens in the 3rd and 4th positions, as to not conflict with IDNs https://datatracker.ietf.org/doc/html/rfc5891
2025-04-11 13:59:25 +10:00
Dean Sheather e7e47537c9 chore: fix gpg forwarding test (#17355) 2025-04-11 03:33:53 +00:00
ケイラ 0472a88c2e chore: update trivy (#17347) 2025-04-10 15:19:39 -06:00
dependabot[bot] a451ea73c3 chore: bump github.com/mark3labs/mcp-go from 0.17.0 to 0.18.0 (#17273)
Bumps [github.com/mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
from 0.17.0 to 0.18.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/mark3labs/mcp-go/releases">github.com/mark3labs/mcp-go's
releases</a>.</em></p>
<blockquote>
<h2>Release v0.18.0</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: add NewToolResultError by <a
href="https://github.com/daimatz"><code>@​daimatz</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/87">mark3labs/mcp-go#87</a></li>
<li>refactor(stdio): improve stdio server message handling by <a
href="https://github.com/winterfx"><code>@​winterfx</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/73">mark3labs/mcp-go#73</a></li>
<li>Add Stderr() Method to StdioMCPClient by <a
href="https://github.com/mashiike"><code>@​mashiike</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/72">mark3labs/mcp-go#72</a></li>
<li>fix java mcp message endpoint by <a
href="https://github.com/a67793581"><code>@​a67793581</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/75">mark3labs/mcp-go#75</a></li>
<li>simplify required field handling in inputSchema by <a
href="https://github.com/yikakia"><code>@​yikakia</code></a> in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/82">mark3labs/mcp-go#82</a></li>
<li>make context available in hooks, add OnRegisterSession hook by <a
href="https://github.com/zahmadsaleem"><code>@​zahmadsaleem</code></a>
in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/92">mark3labs/mcp-go#92</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/daimatz"><code>@​daimatz</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/87">mark3labs/mcp-go#87</a></li>
<li><a href="https://github.com/winterfx"><code>@​winterfx</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/73">mark3labs/mcp-go#73</a></li>
<li><a href="https://github.com/mashiike"><code>@​mashiike</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/72">mark3labs/mcp-go#72</a></li>
<li><a href="https://github.com/yikakia"><code>@​yikakia</code></a> made
their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/82">mark3labs/mcp-go#82</a></li>
<li><a
href="https://github.com/zahmadsaleem"><code>@​zahmadsaleem</code></a>
made their first contribution in <a
href="https://redirect.github.com/mark3labs/mcp-go/pull/92">mark3labs/mcp-go#92</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/mark3labs/mcp-go/compare/v0.17.0...v0.18.0">https://github.com/mark3labs/mcp-go/compare/v0.17.0...v0.18.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/a0e968a752722d87063eb36ea0d55938e752f6dd"><code>a0e968a</code></a>
feat: add context to hooks (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/92">#92</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/607d6c29bb8f56bc30e3154e99e58da1db78fcb9"><code>607d6c2</code></a>
simplify required field handling in inputSchema (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/82">#82</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/6d840a447783c1d342b673d8d06069b96b362a1b"><code>6d840a4</code></a>
fix java mcp message endpoint (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/75">#75</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/051cda5533c70021240e7eae61c0a379511abda7"><code>051cda5</code></a>
Add Stderr() Method to StdioMCPClient (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/72">#72</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/2ea0c97e4a15b5a6bf1c354cd3734a6ed8fbb194"><code>2ea0c97</code></a>
refactor(stdio): improve stdio server message handling (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/73">#73</a>)</li>
<li><a
href="https://github.com/mark3labs/mcp-go/commit/ec9e8a21fee1bbb7d392a14c1cb2463398eaab7b"><code>ec9e8a2</code></a>
add NewToolResultError (<a
href="https://redirect.github.com/mark3labs/mcp-go/issues/87">#87</a>)</li>
<li>See full diff in <a
href="https://github.com/mark3labs/mcp-go/compare/v0.17.0...v0.18.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/mark3labs/mcp-go&package-manager=go_modules&previous-version=0.17.0&new-version=0.18.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-10 20:22:57 +00:00
Edward Angert 9978eb63c4 docs: rename coder-ai directory to avoid wildcard removal (#17348)
to something that doesn't get caught in a wildcard redirect

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-10 16:21:20 -04:00
ケイラ 859dd2fc3f feat: add dynamic parameters websocket endpoint (#17165) 2025-04-10 14:08:50 -06:00
Edward Angert c9682cb6cf docs: hotfix rename coder-ai readme to index (#17346)
[preview](https://coder.com/docs/@hotfix-ai-coder-top/)

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-10 19:33:46 +00:00
Edward Angert e5ba8b7912 docs: update aws instance recommendations (#17344)
from @jatcod3r on Slack:

> for the AWS recs on our [validated
arch](https://coder.com/docs/admin/infrastructure/validated-architectures/1k-users)
docs, should we be referencing customers to use non-T type instances?
> Once you've exceeded EC2's [CPU
credits](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html)
Coder starts performing poorly.
> We do suggest to [scale for peak
demand](https://coder.com/docs/tutorials/best-practices/scale-coder#scaling-3),
so does recommending something from the
[cpu](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized) or
[memory
optimized](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized)
types make sense?


[preview](https://coder.com/docs/@aws-ec2-arch/admin/infrastructure/validated-architectures#aws-instance-types)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-10 14:35:29 -04:00
Edward Angert ed20bab3e0 docs: move AI-agent docs out of tutorials and into a top-level section (#17231)
redirects in: https://github.com/coder/coder.com/pull/873

[preview](https://coder.com/docs/@move-ai-agents-up-1/coder-ai)

- [x] icon
- [x] shorten ~Modify or truncate the current~ title ~to reduce its
length for improved readability, conciseness, or formatting
consistency.~
- [x] Best practices & adding tools via MCP - edit title, desc, headings

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-10 14:21:29 -04:00
Cian Johnston 1e0051a9a2 feat(testutil): add GetRandomNameHyphenated (#17342)
This started coming up more often for me, so time for a test helper!

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-10 19:08:38 +01:00
ケイラ 46d4b28384 chore: add x-authz-checks debug header when running in dev mode (#16873) 2025-04-10 11:36:27 -06:00
Mathias Fredriksson 25fb34cabe feat(agent): implement recreate for devcontainers (#17308)
This change implements an interface for running `@devcontainers/cli up`
and an API endpoint on the agent for triggering recreate for a running
devcontainer.

A couple of limitations:

1. Synchronous HTTP request, meaning the browser might choose to time it
out before it's done => no result/error (and devcontainer cli command
probably gets killed via ctx cancel).
2. Logs are only written to agent logs via slog, not as a "script" in
the UI.

Both 1 and 2 will be improved in future refactors.

Fixes coder/internal#481
Fixes coder/internal#482
2025-04-10 16:16:16 +03:00
Danielle Maywood 6dd1056025 feat(coderd/notifications): group workspace build failure report (#17306)
Closes https://github.com/coder/coder/issues/15745

Instead of sending X many reports to a single template admin, we instead
send only 1.
2025-04-10 13:32:19 +01:00
Mathias Fredriksson 33b9487899 fix(agent/agentcontainers/dcspec): generate unmarshalers and add tests (#17330)
This change allows proper unmarshaling of `devcontainer.json` and will
no longer break EnvInfoer or the Web Terminal.

Fixes coder/internal#556
2025-04-10 12:10:58 +00:00
Spike Curtis c1816e3674 fix(agent): fix deadlock if closed while starting listeners (#17329)
fixes #17328

Fixes a deadlock if we close the Agent in the middle of starting listeners on the tailnet.
2025-04-10 12:46:19 +04:00
Jon Ayers 8faaa14820 chore: update Terraform to 1.11.4 (#17323)
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-09 22:50:15 -04:00
ケイラ f2fb0caf46 chore: remove usage of github.com/go-chi/render (#17324) 2025-04-09 15:35:10 -06:00
Steven Masley 0b58798a1a feat: remove site wide perms from creating a workspace (#17296)
Creating a workspace required `read` on site wide `user`. 
Only organization permissions should be required.
2025-04-09 14:35:43 -05:00
Michael Smith a03a54dd14 fix(site): resolve all Array.prototype.toSorted and Array.prototype.sort bugs (#17307)
Closes https://github.com/coder/coder/issues/16759

## Changes made
- Replaced all instances of `Array.prototype.toSorted` with
`Array.prototype.sort` to provide better support for older browsers
- Updated all `Array.prototype.sort` calls where necessary to remove
risks of mutation render bugs
- Refactored some code (moved things around, added comments) to make it
more clear that certain `.sort` calls are harmless and don't have any
risks
2025-04-09 15:17:02 -04:00
Edward Angert d17bcc727b docs: update note markdown in parameters (#17318)
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-09 18:53:20 +00:00
Mathias Fredriksson 98c05b3568 test(agent/agentssh): fix macos signal flake during close (#17313)
Fixes coder/internal#558
2025-04-09 20:28:32 +03:00
Edward Angert 109e73bf97 docs: add details on external authentication priority (#17164)
## Issue

Closes #16875 

Clarify how Coder authentication works with Git providers, particularly
the order of authentication methods used.

## Changes Made

I've updated the External Authentication documentation to:

1. Clarify that Coder first attempts to use external auth provider
tokens when available, and only defaults to SSH authentication if no
tokens are available
2. Add more detailed explanations about both authentication methods
3. Improve the description of how the `coder gitssh` command works with
existing and Coder-generated SSH keys

## Verification

Claude verified that this accurately describes the behavior of the
codebase by reviewing the `gitssh.go` implementation, which shows how
Coder handles SSH authentication as a fallback when external auth is not
available.


[preview](https://coder.com/docs/@16875-git-workspace-auth/admin/external-auth)

<sub>🤖 Generated with https://claude.ai/code</sub>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Ben Potter <me@bpmct.net>
Co-authored-by: M Atif Ali <atif@coder.com>
Co-authored-by: Bruno Quaresma <bruno@coder.com>
Co-authored-by: Kyle Carberry <kyle@coder.com>
Co-authored-by: Cian Johnston <cian@coder.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jon Ayers <jon@coder.com>
Co-authored-by: Hugo Dutka <hugo@coder.com>
Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
Co-authored-by: Michael Smith <throwawayclover@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Sas Swart <sas.swart.cdk@gmail.com>
2025-04-09 15:16:00 +00:00
Spike Curtis 3f3e2017bd fix: fix http cache dir creation order in coderdtest (#17303)
fixes coder/internal#565

Fixes the ordering of creating the HTTP cache temp dir with respect to
starting the Coderd HTTP server, so that they are cleaned up in the
correct (reverse) order.
2025-04-09 11:19:48 +00:00
Cian Johnston 43b1a034b1 chore(agent/agentscripts): disable TestTimeout on macOS (#17300) 2025-04-09 08:23:43 +00:00
Cian Johnston a8fbe71a22 chore(cli): increase healthcheck timeout in TestSupportbundle (#17291)
Fixes https://github.com/coder/internal/issues/272

* Increases healthcheck timeout in tests. This seems to be the most
usual cause of test failures.
* Adds a non-nilness check before caching a healthcheck report.
* Modifies the HTTP response code to 503 (was 404) when no healthcheck
report is available. 503 seems to be a better indicator of the server
state in this case, whereas 404 could be misinterpreted as a typo in the
healthcheck URL.
2025-04-09 09:21:17 +01:00
Cian Johnston 8d122aa4ab chore(cli): avoid use of testutil.RandomPort() in prometheus test (#17297)
Should hopefully fix https://github.com/coder/internal/issues/282

Instead of picking a random port for the prometheus server, listen on
`:0` and read the port from the CLI stdout.
2025-04-09 09:20:47 +01:00
Utsavkumar Lal 0e658219b2 feat: support filtering users table by login type (#17238)
#15896 Mentions ability to add support for filtering by login type

The issue mentions that backend API support exists but the backend did
not seem to have the support for this filter. So I have added the
ability to filter it.

I also added a corresponding update to readme file to make sure the docs
will correctly showcase this feature
2025-04-09 13:59:41 +10:00
Steven Masley f2d24bc3f4 chore: add custom samesite options to auth cookies (#16885)
Allows controlling `samesite` cookie settings from deployment values
2025-04-08 16:39:21 -05:00
Steven Masley 52d555880c chore: add custom samesite options to auth cookies (#16885)
Allows controlling `samesite` cookie settings from the deployment config
2025-04-08 14:15:14 -05:00
Cian Johnston 389e88ec82 chore(cli): refactor TestServer/Prometheus to use testutil.Eventually (#17295)
Updates https://github.com/coder/internal/issues/282

Refactors existing tests to use `testutil.Eventually` which plays nicer
with `testutil.Context`.
2025-04-08 16:53:22 +01:00
Cian Johnston 44ddc9f654 chore(agent/agentscripts): increase timeout in TestTimeout (#17293)
Fixes https://github.com/coder/internal/issues/329

This was due to a race between the process starting and the timeout of
the agent startup script executor. I'm taking the 'lazy' route here and
increasing the timeout to 100ms. This does technically mean that this
makes the test 100 times longer to execute. However, if it takes more
than 100ms to run a `sleep infinity` command on our test runner, I think
we have other issues.
2025-04-08 14:35:13 +00:00
Spike Curtis b1f59aafc1 fix: stop checking gauges unrelated to TestAgent_Stats_Magic (#17290)
Fixes https://github.com/coder/internal/issues/564

The test is asserting too much, including stats guages that are not directly related to the thing we are trying to test: ConnectionCount, RxBytes, and TxBytes.  I think the author assumed that these are counts that only go up, but they are guages and eventually zero back out, so there are race condtions where not all of them are non-zero at the same time.
2025-04-08 17:01:21 +04:00
Marcin Tojek 88b7c9ef5d feat: install more terminal fonts (#17289)
Related: https://github.com/coder/coder/issues/15024
2025-04-08 14:36:15 +02:00
dependabot[bot] 3487f37f9a chore: bump github.com/go-chi/httprate from 0.14.1 to 0.15.0 (#17171)
Bumps [github.com/go-chi/httprate](https://github.com/go-chi/httprate)
from 0.14.1 to 0.15.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/go-chi/httprate/releases">github.com/go-chi/httprate's
releases</a>.</em></p>
<blockquote>
<h2>v0.15.0</h2>
<ul>
<li>upgrade to xxhash v3</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/go-chi/httprate/commit/c0b6272bcac673c105a4d29c98dd9be27a0d644d"><code>c0b6272</code></a>
upgrade to xxh3 hashing pkg (<a
href="https://redirect.github.com/go-chi/httprate/issues/54">#54</a>)</li>
<li><a
href="https://github.com/go-chi/httprate/commit/9d627fb3c8a009b20ae198abe84b3a1d10a22a94"><code>9d627fb</code></a>
Update README.md: add missing 'time' import in code example (<a
href="https://redirect.github.com/go-chi/httprate/issues/49">#49</a>)</li>
<li><a
href="https://github.com/go-chi/httprate/commit/24ebb38d02ea7de820e34f890c4206cf6b891955"><code>24ebb38</code></a>
Try to fix Github action access issue (<a
href="https://redirect.github.com/go-chi/httprate/issues/51">#51</a>)</li>
<li>See full diff in <a
href="https://github.com/go-chi/httprate/compare/v0.14.1...v0.15.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-chi/httprate&package-manager=go_modules&previous-version=0.14.1&new-version=0.15.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 09:48:35 +00:00
dependabot[bot] f935e2a1d2 chore: bump github.com/go-playground/validator/v10 from 10.25.0 to 10.26.0 (#17173)
Bumps
[github.com/go-playground/validator/v10](https://github.com/go-playground/validator)
from 10.25.0 to 10.26.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/go-playground/validator/releases">github.com/go-playground/validator/v10's
releases</a>.</em></p>
<blockquote>
<h2>v10.26.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Use correct pointer in errors.As(). Fix &quot;panic: errors: *target
must be interface or implement error&quot; in examples. by <a
href="https://github.com/antonsoroko"><code>@​antonsoroko</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1378">go-playground/validator#1378</a></li>
<li>Create dependabot by <a
href="https://github.com/nodivbyzero"><code>@​nodivbyzero</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1373">go-playground/validator#1373</a></li>
<li>Bump golangci/golangci-lint-action from 4 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1381">go-playground/validator#1381</a></li>
<li>Bump golang.org/x/text from 0.21.0 to 0.22.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1383">go-playground/validator#1383</a></li>
<li>Bump golang.org/x/crypto from 0.32.0 to 0.33.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1382">go-playground/validator#1382</a></li>
<li>feat(translations): improve Indonesian translations and add tests by
<a href="https://github.com/fathiraz"><code>@​fathiraz</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1376">go-playground/validator#1376</a></li>
<li>Fix time.Duration translation error by <a
href="https://github.com/nodivbyzero"><code>@​nodivbyzero</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1154">go-playground/validator#1154</a></li>
<li>Update Project Status button by <a
href="https://github.com/nodivbyzero"><code>@​nodivbyzero</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1380">go-playground/validator#1380</a></li>
<li>Remove gitter.im link from README.md by <a
href="https://github.com/nodivbyzero"><code>@​nodivbyzero</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1366">go-playground/validator#1366</a></li>
<li>Docs: fix <code>Base64RawURL</code> usage by <a
href="https://github.com/196Ikuchil"><code>@​196Ikuchil</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1336">go-playground/validator#1336</a></li>
<li>Fix length check on dns_rfc1035_label tag by <a
href="https://github.com/KimNorgaard"><code>@​KimNorgaard</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1214">go-playground/validator#1214</a></li>
<li>Add Korean by <a
href="https://github.com/jkh0kr"><code>@​jkh0kr</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1338">go-playground/validator#1338</a></li>
<li>add german translations by <a
href="https://github.com/max-weis"><code>@​max-weis</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1322">go-playground/validator#1322</a></li>
<li>Update workflow to support the last three Go versions by <a
href="https://github.com/nodivbyzero"><code>@​nodivbyzero</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1393">go-playground/validator#1393</a></li>
<li>Fix: Nil pointer dereference in Arabic translations by <a
href="https://github.com/BlackSud0"><code>@​BlackSud0</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1391">go-playground/validator#1391</a></li>
<li>Translate to thai by <a
href="https://github.com/maetad"><code>@​maetad</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1202">go-playground/validator#1202</a></li>
<li>Feat: add EIN validation by <a
href="https://github.com/henrriusdev"><code>@​henrriusdev</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1384">go-playground/validator#1384</a></li>
<li>Fix reference to parameter name in docs by <a
href="https://github.com/yegvla"><code>@​yegvla</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1400">go-playground/validator#1400</a></li>
<li>use mail.ParseAddress to cover missing email validations by <a
href="https://github.com/eladb2011"><code>@​eladb2011</code></a> in <a
href="https://redirect.github.com/go-playground/validator/pull/1395">go-playground/validator#1395</a></li>
<li>Update linter to v2.0.2 by <a
href="https://github.com/nodivbyzero"><code>@​nodivbyzero</code></a> in
<a
href="https://redirect.github.com/go-playground/validator/pull/1405">go-playground/validator#1405</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/antonsoroko"><code>@​antonsoroko</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1378">go-playground/validator#1378</a></li>
<li><a
href="https://github.com/dependabot"><code>@​dependabot</code></a> made
their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1381">go-playground/validator#1381</a></li>
<li><a href="https://github.com/fathiraz"><code>@​fathiraz</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1376">go-playground/validator#1376</a></li>
<li><a
href="https://github.com/196Ikuchil"><code>@​196Ikuchil</code></a> made
their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1336">go-playground/validator#1336</a></li>
<li><a
href="https://github.com/KimNorgaard"><code>@​KimNorgaard</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1214">go-playground/validator#1214</a></li>
<li><a href="https://github.com/jkh0kr"><code>@​jkh0kr</code></a> made
their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1338">go-playground/validator#1338</a></li>
<li><a href="https://github.com/max-weis"><code>@​max-weis</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1322">go-playground/validator#1322</a></li>
<li><a href="https://github.com/BlackSud0"><code>@​BlackSud0</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1391">go-playground/validator#1391</a></li>
<li><a href="https://github.com/maetad"><code>@​maetad</code></a> made
their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1202">go-playground/validator#1202</a></li>
<li><a
href="https://github.com/henrriusdev"><code>@​henrriusdev</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1384">go-playground/validator#1384</a></li>
<li><a href="https://github.com/yegvla"><code>@​yegvla</code></a> made
their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1400">go-playground/validator#1400</a></li>
<li><a href="https://github.com/eladb2011"><code>@​eladb2011</code></a>
made their first contribution in <a
href="https://redirect.github.com/go-playground/validator/pull/1395">go-playground/validator#1395</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/go-playground/validator/compare/v10.25.0...v10.26.0">https://github.com/go-playground/validator/compare/v10.25.0...v10.26.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/go-playground/validator/commit/433b08283c14b1def28e8f05e36c2bed2f13b3f4"><code>433b082</code></a>
Update linter to v2.0.2 (<a
href="https://redirect.github.com/go-playground/validator/issues/1405">#1405</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/859202275556dac82d4460234867c5c5988d06fd"><code>8592022</code></a>
use mail.ParseAddress to cover missing email validations (<a
href="https://redirect.github.com/go-playground/validator/issues/1395">#1395</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/271abb312cd958fd1c61b58983ecab31026eb252"><code>271abb3</code></a>
Fix reference to parameter name in docs (<a
href="https://redirect.github.com/go-playground/validator/issues/1400">#1400</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/79c42ad73c1fdebee04c93ac6a0e132353662dc6"><code>79c42ad</code></a>
Feat: add EIN validation (<a
href="https://redirect.github.com/go-playground/validator/issues/1384">#1384</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/2cadaff20364eef00f8711e1b6a0dfcc2aceee14"><code>2cadaff</code></a>
Translate to thai (<a
href="https://redirect.github.com/go-playground/validator/issues/1202">#1202</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/bae7f6d3cb253fbd5dddcdf339f8460fa8d091c3"><code>bae7f6d</code></a>
Fix: Nil pointer dereference in Arabic translations (<a
href="https://redirect.github.com/go-playground/validator/issues/1391">#1391</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/909c504042f17c83dc76e8a2c11efd3dd41bd212"><code>909c504</code></a>
Update workflow to support the last three Go versions (<a
href="https://redirect.github.com/go-playground/validator/issues/1393">#1393</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/09c1323276ffada71562c1b8bf0554a0ed5ddd1d"><code>09c1323</code></a>
add german translations (<a
href="https://redirect.github.com/go-playground/validator/issues/1322">#1322</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/45dd6e3bd61a7659b16d9c624e3e0174223a5fd6"><code>45dd6e3</code></a>
Add Korean (<a
href="https://redirect.github.com/go-playground/validator/issues/1338">#1338</a>)</li>
<li><a
href="https://github.com/go-playground/validator/commit/97d2bf07aad31b97b64fcd8213f922f159e62361"><code>97d2bf0</code></a>
Fix length check on dns_rfc1035_label tag (<a
href="https://redirect.github.com/go-playground/validator/issues/1214">#1214</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/go-playground/validator/compare/v10.25.0...v10.26.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-playground/validator/v10&package-manager=go_modules&previous-version=10.25.0&new-version=10.26.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 09:17:47 +00:00
Michael Suchacz ce22de8d15 feat: log long-lived connections acceptance (#17219)
Closes #16904
2025-04-08 08:30:05 +00:00
Thomas Kosiewski abe3ad68f5 fix: add continue-on-error to SBOM generation and force flag to cosign clean (#17288)
This PR makes the SBOM generation and attestation process more resilient
by:

1. Adding `continue-on-error: true` to the SBOM generation steps in both
CI and release workflows
2. Adding `--force=true` flag to all `cosign clean` commands to ensure
they don't fail if in a non-interactive shell (which is the case for CI)

Change-Id: Ide303c059b1a3d0e3fd77863310e99668325bc69
Signed-off-by: Thomas Kosiewski <tk@coder.com>

Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-04-08 10:29:00 +02:00
Edward Angert 0e878a8e98 docs: rename codervpn to coder connect (#16833)
part of: https://github.com/coder/internal/issues/459

- [x] Text
- [x] Screenshots
  - [x] MacOS
  - [x] Windows

[preview](https://coder.com/docs/@459-coder-connect/user-guides/desktop)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
2025-04-08 12:00:23 +04:00
coryb 12e5718b99 feat(provisioner): propagate trace info (#17166)
If tracing is enabled, propagate the trace information to the terraform
provisioner via environment variables. This sets the `TRACEPARENT`
environment variable using the default W3C trace propagators. Users can
choose to continue the trace by adding new spans in the provisioner by
reading from the environment like:

ctx := env.ContextWithRemoteSpanContext(context.Background(),
os.Environ())

---------

Co-authored-by: Spike Curtis <spike@spikecurtis.com>
2025-04-08 11:58:28 +04:00
Spike Curtis 9eeb506ae5 feat: modify config-ssh to set the host suffix (#17280)
Wires up `config-ssh` command to use a hostname suffix if configured.

part of: #16828


e.g. `coder config-ssh --hostname-suffix spiketest` gives:

```
# ------------START-CODER-----------
# This section is managed by coder. DO NOT EDIT.
#
# You should not hand-edit this section unless you are removing it, all
# changes will be lost when running "coder config-ssh".
#
# Last config-ssh options:
# :hostname-suffix=spiketest
#
Host coder.* *.spiketest
        ConnectTimeout=0
        StrictHostKeyChecking=no
        UserKnownHostsFile=/dev/null
        LogLevel ERROR
        ProxyCommand /home/coder/repos/coder/build/coder_config_ssh --global-config /home/coder/.config/coderv2 ssh --stdio --ssh-host-prefix coder. --hostname-suffix spiketest %h
# ------------END-CODER------------
```
2025-04-08 11:48:18 +04:00
ケイラ 114ba4593b chore: fix swagger type of AuditLog AdditionalFields (#17286) 2025-04-07 13:48:58 -06:00
Edward Angert d0aff04aef docs: remove blank inbox doc (#17285)
[preview](https://coder.com/docs/@hotfix-inbox-doc)

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-07 14:19:45 -04:00
Edward Angert 2f6682a46f docs: add zed code_app to extending-templates doc (#17281)
continuation of #17236  (thanks @sharkymark )

adds zed as a coder_app to
<https://coder.com/docs/admin/templates/extending-templates>



[preview](https://coder.com/docs/@17236-zed-app/admin/templates/extending-templates#coder-app-examples)

---------

Co-authored-by: sharkymark <mtm20176@gmail.com>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-07 14:00:43 -04:00
Spike Curtis d312e82a51 feat: support --hostname-suffix flag on coder ssh (#17279)
Adds `hostname-suffix` flag to `coder ssh` command for use in SSH Config ProxyCommands.

Also enforces that Coder server doesn't start the suffix with a dot.

part of: #16828
2025-04-07 21:33:33 +04:00
Aaron Lehmann aa0a63a295 fix(agent): log correct error variable in createTailnet (#17283) 2025-04-07 16:32:52 +00:00
Thomas Kosiewski f48a24c18e feat: add SBOM generation and attestation to GitHub workflow (#17277)
Move SBOM generation and attestation to GitHub workflow

This PR moves the SBOM generation and attestation process from the `build_docker.sh` script to the GitHub workflow. The change:

1. Removes SBOM generation and attestation from the `build_docker.sh` script
2. Adds a new "SBOM Generation and Attestation" step in the GitHub workflow
3. Generates and attests SBOMs for both multi-arch images and latest tags when applicable

This approach ensures SBOM generation happens once for the final multi-architecture image rather than for each architecture separately.

Change-Id: I2e15d7322ddec933bbc9bd7880abba9b0842719f
Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-04-07 17:54:05 +02:00
Garrett Delfosse fc471eb384 fix: handle vscodessh style workspace names in coder ssh (#17154)
Fixes an issue where old ssh configs that use the
`owner--workspace--agent` format will fail to properly use the `coder
ssh` command since we migrated off the `coder vscodessh` command.
2025-04-07 10:06:58 -04:00
Marcin Tojek 743d308eb3 feat: support multiple terminal fonts (#17257)
Fixes: https://github.com/coder/coder/issues/15024
2025-04-07 14:30:10 +02:00
dependabot[bot] 30f41cdd42 chore: bump github.com/valyala/fasthttp from 1.59.0 to 1.60.0 (#17274)
Bumps [github.com/valyala/fasthttp](https://github.com/valyala/fasthttp)
from 1.59.0 to 1.60.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/valyala/fasthttp/releases">github.com/valyala/fasthttp's
releases</a>.</em></p>
<blockquote>
<h2>v1.60.0</h2>
<h2>What's Changed</h2>
<ul>
<li>perf: split delAllArgs into delAllArgs and delAllArgsStable by <a
href="https://github.com/ksw2000"><code>@​ksw2000</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1945">valyala/fasthttp#1945</a></li>
<li>fix: accept invalid headers with a space by <a
href="https://github.com/ksw2000"><code>@​ksw2000</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1953">valyala/fasthttp#1953</a></li>
<li>Drop support for Go 1.21, add support for 1.24 by <a
href="https://github.com/erikdubbelboer"><code>@​erikdubbelboer</code></a>
in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1959">valyala/fasthttp#1959</a></li>
<li>chore(deps): bump github.com/klauspost/compress from 1.17.11 to
1.18.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1958">valyala/fasthttp#1958</a></li>
<li>add related project for opentelemetry-go-auto-instrumentation by <a
href="https://github.com/123liuziming"><code>@​123liuziming</code></a>
in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1962">valyala/fasthttp#1962</a></li>
<li>Fix normalizeHeaderValue by <a
href="https://github.com/erikdubbelboer"><code>@​erikdubbelboer</code></a>
in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1963">valyala/fasthttp#1963</a></li>
<li>chore(deps): bump golang.org/x/net from 0.35.0 to 0.36.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1968">valyala/fasthttp#1968</a></li>
<li>chore(deps): bump securego/gosec from 2.22.1 to 2.22.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1972">valyala/fasthttp#1972</a></li>
<li>chore(deps): bump golang.org/x/net from 0.36.0 to 0.37.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1971">valyala/fasthttp#1971</a></li>
<li>Update golangci-lint to v2 by <a
href="https://github.com/erikdubbelboer"><code>@​erikdubbelboer</code></a>
in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1980">valyala/fasthttp#1980</a></li>
<li>chore(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1983">valyala/fasthttp#1983</a></li>
<li>Remove idleConns mutex for every request by <a
href="https://github.com/erikdubbelboer"><code>@​erikdubbelboer</code></a>
in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1986">valyala/fasthttp#1986</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/123liuziming"><code>@​123liuziming</code></a>
made their first contribution in <a
href="https://redirect.github.com/valyala/fasthttp/pull/1962">valyala/fasthttp#1962</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/valyala/fasthttp/compare/v1.59.0...v1.60.0">https://github.com/valyala/fasthttp/compare/v1.59.0...v1.60.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/valyala/fasthttp/commit/752b0e70040eee46b291b9dedd70266d8aa3e2e7"><code>752b0e7</code></a>
Remove idleConns mutex for every request (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1986">#1986</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/bf3f552c8e564472d6e7aae08804bcf0813f1f73"><code>bf3f552</code></a>
chore(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1983">#1983</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/4891fc5304e3ab9e23e9258a39736a3726b626c2"><code>4891fc5</code></a>
Update golangci-lint to v2 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1980">#1980</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/30b09beff11be4282c37ef6b7d8854589d565447"><code>30b09be</code></a>
Fix untyped int constant 4294967295</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/4269e2d68c33f2242e61f67ad4e104ba26fc4c1c"><code>4269e2d</code></a>
chore(deps): bump golang.org/x/net from 0.36.0 to 0.37.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1971">#1971</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/1353ca59f2044a74111d80087a5e762a71a3e1a2"><code>1353ca5</code></a>
chore(deps): bump securego/gosec from 2.22.1 to 2.22.2 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1972">#1972</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/6c07c2f523de17c866ac4cf86d08386e7bad55e4"><code>6c07c2f</code></a>
chore(deps): bump golang.org/x/net from 0.35.0 to 0.36.0 (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1968">#1968</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/69dc7b1280e58dac05ab46c423b5b7f14cc88fab"><code>69dc7b1</code></a>
Update the supported version to the same as Go itself (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1967">#1967</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/b8969ed8dcb5cba0b037f3fe091a0933fc786a28"><code>b8969ed</code></a>
Fix normalizeHeaderValue (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1963">#1963</a>)</li>
<li><a
href="https://github.com/valyala/fasthttp/commit/31e34c5fe0c3dd3090b0c9d662b74bab1dc87f6d"><code>31e34c5</code></a>
add related project for opentelemetry-go-auto-instrumentation (<a
href="https://redirect.github.com/valyala/fasthttp/issues/1962">#1962</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/valyala/fasthttp/compare/v1.59.0...v1.60.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/valyala/fasthttp&package-manager=go_modules&previous-version=1.59.0&new-version=1.60.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 12:18:23 +00:00
dependabot[bot] 37ef4d8cb9 chore: bump github.com/coreos/go-oidc/v3 from 3.13.0 to 3.14.1 (#17276)
Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc)
from 3.13.0 to 3.14.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/coreos/go-oidc/releases">github.com/coreos/go-oidc/v3's
releases</a>.</em></p>
<blockquote>
<h2>v3.14.1</h2>
<h2>What's Changed</h2>
<ul>
<li>oidctest: fix import by <a
href="https://github.com/ericchiang"><code>@​ericchiang</code></a> in <a
href="https://redirect.github.com/coreos/go-oidc/pull/457">coreos/go-oidc#457</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/coreos/go-oidc/compare/v3.14.0...v3.14.1">https://github.com/coreos/go-oidc/compare/v3.14.0...v3.14.1</a></p>
<h2>v3.14.0</h2>
<h2>What's Changed</h2>
<ul>
<li>oidc/oidctest: add new package by <a
href="https://github.com/ericchiang"><code>@​ericchiang</code></a> in <a
href="https://redirect.github.com/coreos/go-oidc/pull/400">coreos/go-oidc#400</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/coreos/go-oidc/compare/v3.13.0...v3.14.0">https://github.com/coreos/go-oidc/compare/v3.13.0...v3.14.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/coreos/go-oidc/commit/a7c457eacb849c163a496b29274242474a8f44ab"><code>a7c457e</code></a>
oidctest: fix import</li>
<li><a
href="https://github.com/coreos/go-oidc/commit/aba1ce200a9dd76b14bbb455d4e5aea55e97cbb3"><code>aba1ce2</code></a>
oidc/oidctest: add new package</li>
<li>See full diff in <a
href="https://github.com/coreos/go-oidc/compare/v3.13.0...v3.14.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/coreos/go-oidc/v3&package-manager=go_modules&previous-version=3.13.0&new-version=3.14.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 12:18:05 +00:00
dependabot[bot] e6dc6fb8c1 chore: bump github.com/open-policy-agent/opa from 1.1.0 to 1.3.0 (#17170)
Bumps
[github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa)
from 1.1.0 to 1.3.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/open-policy-agent/opa/releases">github.com/open-policy-agent/opa's
releases</a>.</em></p>
<blockquote>
<h2>v1.3.0</h2>
<p>This release contains a mix of features, bugfixes, and dependency
updates.</p>
<h3>New Buffer Option for Decision Logs (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/5724">#5724</a>)</h3>
<p>A new, optional, buffering mechanism has been added to decision
logging.
The default buffer is designed around making precise memory footprint
guarantees, which can produce lock contention at high loads, negatively
impacting query performance.
The new event-based buffer is designed to reduce lock contention and
improve performance at high loads, but sacrifices the memory footprint
guarantees of the default buffer.</p>
<p>The new event-based buffer is enabled by setting the
<code>decision_logs.reporting.buffer_type</code> <a
href="https://www.openpolicyagent.org/docs/latest/configuration/#decision-logs">configuration
option</a> to <code>event</code>.</p>
<p>For more details, see the decision log plugin <a
href="https://github.com/open-policy-agent/opa/blob/main/v1/plugins/logs/README.md">README</a>.</p>
<p>Reported by <a
href="https://github.com/mjungsbluth"><code>@​mjungsbluth</code></a>,
authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a></p>
<h3>OpenTelemetry: HTTP Support and Expanded Batch Span Configuration
(<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7412">#7412</a>)</h3>
<p>Distributed tracing through OpenTelemetry has been extended to
support HTTP collectors (enabled by setting the
<code>distributed_tracing.type</code> configuration option to
<code>http</code>).
Additionally, configuration has been expanded with fine-grained batch
span processor <a
href="https://www.openpolicyagent.org/docs/latest/configuration/#distributed-tracing">options</a>.</p>
<p>Authored and reported by <a
href="https://github.com/sqyang94"><code>@​sqyang94</code></a></p>
<h3>Runtime, Tooling, SDK</h3>
<ul>
<li>compile: Require multi-term entrypoint paths for optimized bundle
building (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7321">#7321</a>)
authored by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a>
reported by <a
href="https://github.com/nikpivkin"><code>@​nikpivkin</code></a></li>
<li>fmt: Allow one liner rule grouping (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/6760">#6760</a>)
authored by <a
href="https://github.com/anderseknert"><code>@​anderseknert</code></a></li>
<li>fmt: Fix v0-compatible fmt with stdin (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7409">#7409</a>)
authored and reported by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>ir: Fix nil pointer deref in Unmarshal() when handling IsSetStmt (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7415">#7415</a>)
authored and reported by <a
href="https://github.com/KrisKennawayDD"><code>@​KrisKennawayDD</code></a></li>
<li>planner: Fix Wasm vs non-Wasm evaluation difference bug related to
the overeager optimization of ref head rules (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7439">#7439</a>)
authored by <a
href="https://github.com/srenatus"><code>@​srenatus</code></a></li>
<li>sdk: Removing repeat args from sub-func call (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7443">#7443</a>)
authored by <a
href="https://github.com/alingse"><code>@​alingse</code></a></li>
<li>tester: Including parameterized test cases in test report counter
(<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7407">#7407</a>)
authored by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a></li>
<li>tester: Only including failed sub-test cases in report summary when
non-verbose (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7426">#7426</a>)
authored by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a></li>
</ul>
<h3>Docs, Website, Ecosystem</h3>
<ul>
<li>docs: Add some notes about AI assisted patches (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7436">#7436</a>)
authored by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>docs: Add query_parameters_to_set (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7405">#7405</a>)
authored by <a
href="https://github.com/sedovmik"><code>@​sedovmik</code></a></li>
<li>docs: Delete reference to license key in Envoy tutorial (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7466">#7466</a>)
authored by <a
href="https://github.com/joostholslag"><code>@​joostholslag</code></a></li>
<li>docs: Fix typo in Envoy tutorial (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7464">#7464</a>)
authored by <a
href="https://github.com/joostholslag"><code>@​joostholslag</code></a></li>
<li>docs: Update slack inviter link (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7450">#7450</a>)
authored by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>docs: Update terraform examples (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7429">#7429</a>)
authored by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>docs: Simplify <code>kind</code> usage instruction in Envoy tutorial
(<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7465">#7465</a>)
authored by <a
href="https://github.com/joostholslag"><code>@​joostholslag</code></a></li>
</ul>
<h3>Miscellaneous</h3>
<ul>
<li>Enable unused-receiver linter (revive) (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7448">#7448</a>)
authored by <a
href="https://github.com/anderseknert"><code>@​anderseknert</code></a></li>
<li>Dependency updates; notably:
<ul>
<li>build(deps): bump github.com/containerd/containerd from 1.7.26 to
1.7.27</li>
<li>build(deps): bump github.com/dgraph-io/badger/v4 from 4.5.1 to
4.6.0</li>
<li>build(deps): bump github.com/opencontainers/image-spec from 1.1.0 to
1.1.1</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md">github.com/open-policy-agent/opa's
changelog</a>.</em></p>
<blockquote>
<h2>1.3.0</h2>
<p>This release contains a mix of features, bugfixes, and dependency
updates.</p>
<h3>New Buffer Option for Decision Logs (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/5724">#5724</a>)</h3>
<p>A new, optional, buffering mechanism has been added to decision
logging.
The default buffer is designed around making precise memory footprint
guarantees, which can produce lock contention at high loads, negatively
impacting query performance.
The new event-based buffer is designed to reduce lock contention and
improve performance at high loads, but sacrifices the memory footprint
guarantees of the default buffer.</p>
<p>The new event-based buffer is enabled by setting the
<code>decision_logs.reporting.buffer_type</code> <a
href="https://www.openpolicyagent.org/docs/latest/configuration/#decision-logs">configuration
option</a> to <code>event</code>.</p>
<p>For more details, see the decision log plugin <a
href="https://github.com/open-policy-agent/opa/blob/main/v1/plugins/logs/README.md">README</a>.</p>
<p>Reported by <a
href="https://github.com/mjungsbluth"><code>@​mjungsbluth</code></a>,
authored by <a
href="https://github.com/sspaink"><code>@​sspaink</code></a></p>
<h3>OpenTelemetry: HTTP Support and Expanded Batch Span Configuration
(<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7412">#7412</a>)</h3>
<p>Distributed tracing through OpenTelemetry has been extended to
support HTTP collectors (enabled by setting the
<code>distributed_tracing.type</code> configuration option to
<code>http</code>).
Additionally, configuration has been expanded with fine-grained batch
span processor <a
href="https://www.openpolicyagent.org/docs/latest/configuration/#distributed-tracing">options</a>.</p>
<p>Authored and reported by <a
href="https://github.com/sqyang94"><code>@​sqyang94</code></a></p>
<h3>Runtime, Tooling, SDK</h3>
<ul>
<li>compile: Require multi-term entrypoint paths for optimized bundle
building (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7321">#7321</a>)
authored by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a>
reported by <a
href="https://github.com/nikpivkin"><code>@​nikpivkin</code></a></li>
<li>fmt: Allow one liner rule grouping (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/6760">#6760</a>)
authored by <a
href="https://github.com/anderseknert"><code>@​anderseknert</code></a></li>
<li>fmt: Fix v0-compatible fmt with stdin (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7409">#7409</a>)
authored and reported by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>ir: Fix nil pointer deref in Unmarshal() when handling IsSetStmt (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7415">#7415</a>)
authored and reported by <a
href="https://github.com/KrisKennawayDD"><code>@​KrisKennawayDD</code></a></li>
<li>planner: Fix Wasm vs non-Wasm evaluation difference bug related to
the overeager optimization of ref head rules (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7439">#7439</a>)
authored by <a
href="https://github.com/srenatus"><code>@​srenatus</code></a></li>
<li>sdk: Removing repeat args from sub-func call (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7443">#7443</a>)
authored by <a
href="https://github.com/alingse"><code>@​alingse</code></a></li>
<li>tester: Including parameterized test cases in test report counter
(<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7407">#7407</a>)
authored by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a></li>
<li>tester: Only including failed sub-test cases in report summary when
non-verbose (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7426">#7426</a>)
authored by <a
href="https://github.com/johanfylling"><code>@​johanfylling</code></a></li>
</ul>
<h3>Docs, Website, Ecosystem</h3>
<ul>
<li>docs: Add some notes about AI assisted patches (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7436">#7436</a>)
authored by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>docs: Add query_parameters_to_set (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7405">#7405</a>)
authored by <a
href="https://github.com/sedovmik"><code>@​sedovmik</code></a></li>
<li>docs: Delete reference to license key in Envoy tutorial (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7466">#7466</a>)
authored by <a
href="https://github.com/joostholslag"><code>@​joostholslag</code></a></li>
<li>docs: Fix typo in Envoy tutorial (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7464">#7464</a>)
authored by <a
href="https://github.com/joostholslag"><code>@​joostholslag</code></a></li>
<li>docs: Update slack inviter link (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7450">#7450</a>)
authored by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>docs: Update terraform examples (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7429">#7429</a>)
authored by <a
href="https://github.com/charlieegan3"><code>@​charlieegan3</code></a></li>
<li>docs: Simplify <code>kind</code> usage instruction in Envoy tutorial
(<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7465">#7465</a>)
authored by <a
href="https://github.com/joostholslag"><code>@​joostholslag</code></a></li>
</ul>
<h3>Miscellaneous</h3>
<ul>
<li>Enable unused-receiver linter (revive) (<a
href="https://redirect.github.com/open-policy-agent/opa/pull/7448">#7448</a>)
authored by <a
href="https://github.com/anderseknert"><code>@​anderseknert</code></a></li>
<li>Dependency updates; notably:
<ul>
<li>build(deps): bump github.com/containerd/containerd from 1.7.26 to
1.7.27</li>
<li>build(deps): bump github.com/dgraph-io/badger/v4 from 4.5.1 to
4.6.0</li>
</ul>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/open-policy-agent/opa/commit/89f48353959c9b08608b6d7160c1f1c5ae2763ee"><code>89f4835</code></a>
Prepare v1.3.0 release (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7467">#7467</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/ee38d8345f4950c6429d4d117e3509c578e36f5f"><code>ee38d83</code></a>
docs/envoy-tutorial-standalone: simplify 'kind' usage instruction (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7465">#7465</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/3d3b45f7522a9e7de3334231d76fbe75d346a677"><code>3d3b45f</code></a>
Delete reference to license key in envoy-tutorial-standalone-envoy.md
(<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7466">#7466</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/004af4c64454eab7b0c2e48aa4aea8dc6fb17eb7"><code>004af4c</code></a>
docs/envoy-tutorial-standalone: fix typo (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7464">#7464</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/cd66fa36e2b6e8ad396dbb7a0f3adc600118c607"><code>cd66fa3</code></a>
feat: new event-based decisions log buffer implementation (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7446">#7446</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/c8febc8625a626b52195c511a37868c85f9f4b9b"><code>c8febc8</code></a>
feat: add more distributed tracing options (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7421">#7421</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/b3b87ffd830b5b1309ffd95ef0f42e9a4e0c071b"><code>b3b87ff</code></a>
fmt: allow one liner rule grouping (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7453">#7453</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/92ae9a014f984ba39bca1ed19c832ddbf259e88f"><code>92ae9a0</code></a>
build(deps): bump github.com/containerd/containerd from 1.7.26 to 1.7.27
(<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7451">#7451</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/f3de1006f9b59f310d32b9433dc6d76d0a4acde5"><code>f3de100</code></a>
docs: Update slack inviter link (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7450">#7450</a>)</li>
<li><a
href="https://github.com/open-policy-agent/opa/commit/bd5ceb514234f2d0a625dff532abe2167f9d824e"><code>bd5ceb5</code></a>
Enable unused-receiver linter (revive) (<a
href="https://redirect.github.com/open-policy-agent/opa/issues/7448">#7448</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/open-policy-agent/opa/compare/v1.1.0...v1.3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/open-policy-agent/opa&package-manager=go_modules&previous-version=1.1.0&new-version=1.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 12:17:11 +00:00
dependabot[bot] a2314ad53c chore: bump github.com/ory/dockertest/v3 from 3.11.0 to 3.12.0 (#17275)
Bumps [github.com/ory/dockertest/v3](https://github.com/ory/dockertest)
from 3.11.0 to 3.12.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ory/dockertest/releases">github.com/ory/dockertest/v3's
releases</a>.</em></p>
<blockquote>
<h2>v3.12.0</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(deps): bump github.com/docker/cli from 26.1.4+incompatible to
27.1.2+incompatible by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/524">ory/dockertest#524</a></li>
<li>chore(deps): bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/514">ory/dockertest#514</a></li>
<li>chore(deps): bump actions/stale from 4 to 9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/526">ory/dockertest#526</a></li>
<li>chore(deps): bump github.com/opencontainers/runc from 1.1.13 to
1.1.15 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/538">ory/dockertest#538</a></li>
<li>chore(deps): bump actions/checkout from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/527">ory/dockertest#527</a></li>
<li>feat: use creds helper by <a
href="https://github.com/GuillaumeSmaha"><code>@​GuillaumeSmaha</code></a>
in <a
href="https://redirect.github.com/ory/dockertest/pull/520">ory/dockertest#520</a></li>
<li>added AuthConfigs to BuildOptions and pass that to BuildImage by <a
href="https://github.com/DGollings"><code>@​DGollings</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/488">ory/dockertest#488</a></li>
<li>add multiple test container example by <a
href="https://github.com/akoserwal"><code>@​akoserwal</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/515">ory/dockertest#515</a></li>
<li>fix: trying to bind to an outbound ip returns an empty list of port
bindings by <a
href="https://github.com/atzoum"><code>@​atzoum</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/533">ory/dockertest#533</a></li>
<li>chore(deps): bump golang.org/x/sys from 0.21.0 to 0.28.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/548">ory/dockertest#548</a></li>
<li>chore(deps): bump actions/stale from 4 to 9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/550">ory/dockertest#550</a></li>
<li>chore(deps): bump actions/checkout from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/549">ory/dockertest#549</a></li>
<li>chore(deps): bump actions/checkout from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/555">ory/dockertest#555</a></li>
<li>chore(deps): bump github.com/docker/cli from 27.1.2+incompatible to
27.4.1+incompatible by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/553">ory/dockertest#553</a></li>
<li>chore(deps): bump github.com/opencontainers/runc from 1.1.15 to
1.2.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/551">ory/dockertest#551</a></li>
<li>chore(deps): bump github.com/stretchr/testify from 1.9.0 to 1.10.0
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/ory/dockertest/pull/547">ory/dockertest#547</a></li>
<li>feat: add support for BuildKit when building images by <a
href="https://github.com/tmc"><code>@​tmc</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/416">ory/dockertest#416</a></li>
<li>chore(deps): bump actions/setup-node from 2.pre.beta to 4.1.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/539">ory/dockertest#539</a></li>
<li>chore(deps): bump actions/stale from 4 to 9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/ory/dockertest/pull/554">ory/dockertest#554</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/GuillaumeSmaha"><code>@​GuillaumeSmaha</code></a>
made their first contribution in <a
href="https://redirect.github.com/ory/dockertest/pull/520">ory/dockertest#520</a></li>
<li><a href="https://github.com/DGollings"><code>@​DGollings</code></a>
made their first contribution in <a
href="https://redirect.github.com/ory/dockertest/pull/488">ory/dockertest#488</a></li>
<li><a href="https://github.com/akoserwal"><code>@​akoserwal</code></a>
made their first contribution in <a
href="https://redirect.github.com/ory/dockertest/pull/515">ory/dockertest#515</a></li>
<li><a href="https://github.com/atzoum"><code>@​atzoum</code></a> made
their first contribution in <a
href="https://redirect.github.com/ory/dockertest/pull/533">ory/dockertest#533</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/ory/dockertest/compare/v3.11.0...v3.12.0">https://github.com/ory/dockertest/compare/v3.11.0...v3.12.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ory/dockertest/commit/8a76ff064a81dda59a3839f908b85e4df79d755a"><code>8a76ff0</code></a>
chore: update repository templates to <a
href="https://github.com/ory/meta/commit/bc60">https://github.com/ory/meta/commit/bc60</a>...</li>
<li><a
href="https://github.com/ory/dockertest/commit/207b20aded3b6876a3acb2a6cdc4447eb8f49bfc"><code>207b20a</code></a>
chore: update repository templates to <a
href="https://github.com/ory/meta/commit/83e7">https://github.com/ory/meta/commit/83e7</a>...</li>
<li><a
href="https://github.com/ory/dockertest/commit/fabf5638cd38b571da9f174f777709da3699e419"><code>fabf563</code></a>
autogen: update license overview</li>
<li><a
href="https://github.com/ory/dockertest/commit/4b1e539f23198fc2718bdc3122af50cb123bd621"><code>4b1e539</code></a>
chore: update repository templates to <a
href="https://github.com/ory/meta/commit/44ef">https://github.com/ory/meta/commit/44ef</a>...</li>
<li><a
href="https://github.com/ory/dockertest/commit/46d1a7b148e4ffbef44b5688c3f814a687d0cc84"><code>46d1a7b</code></a>
chore: update repository templates to <a
href="https://github.com/ory/meta/commit/c091">https://github.com/ory/meta/commit/c091</a>...</li>
<li><a
href="https://github.com/ory/dockertest/commit/13e6e33fbdb15fdc137d671a8109cdafee61a9d3"><code>13e6e33</code></a>
chore(deps): bump actions/stale from 4 to 9 (<a
href="https://redirect.github.com/ory/dockertest/issues/554">#554</a>)</li>
<li><a
href="https://github.com/ory/dockertest/commit/91b7d0b413252b891483b989ddc2ecda394b14cf"><code>91b7d0b</code></a>
chore(deps): bump actions/setup-node from 2.pre.beta to 4.1.0 (<a
href="https://redirect.github.com/ory/dockertest/issues/539">#539</a>)</li>
<li><a
href="https://github.com/ory/dockertest/commit/28c8c5b6ab911beb07fc08922fd42fb74ea82b19"><code>28c8c5b</code></a>
chore(deps): bump github.com/containerd/continuity from 0.4.3 to 0.4.5
(<a
href="https://redirect.github.com/ory/dockertest/issues/545">#545</a>)</li>
<li><a
href="https://github.com/ory/dockertest/commit/eec3a4f420353447100008b96eb33c3b5509577b"><code>eec3a4f</code></a>
feat: add support for BuildKit when building images (<a
href="https://redirect.github.com/ory/dockertest/issues/416">#416</a>)</li>
<li><a
href="https://github.com/ory/dockertest/commit/f6e65ba5e18bbca77c5d27d768d67268c01c7178"><code>f6e65ba</code></a>
chore(deps): bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (<a
href="https://redirect.github.com/ory/dockertest/issues/547">#547</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/ory/dockertest/compare/v3.11.0...v3.12.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/ory/dockertest/v3&package-manager=go_modules&previous-version=3.11.0&new-version=3.12.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 12:03:43 +00:00
dependabot[bot] 4615d29698 chore: bump the x group across 1 directory with 6 updates (#17272)
Bumps the x group with 3 updates in the / directory:
[golang.org/x/crypto](https://github.com/golang/crypto),
[golang.org/x/net](https://github.com/golang/net) and
[golang.org/x/oauth2](https://github.com/golang/oauth2).

Updates `golang.org/x/crypto` from 0.36.0 to 0.37.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/crypto/commit/959f8f3db0fb8c3fb1f9507101058dda21e1fdcf"><code>959f8f3</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="https://github.com/golang/crypto/commit/769bcd6997ac6f3154e27b73b3587295f7720e66"><code>769bcd6</code></a>
ssh: use the configured rand in kex init</li>
<li><a
href="https://github.com/golang/crypto/commit/d0a798f774735c176ed0d3500ac986957a02660f"><code>d0a798f</code></a>
cryptobyte: fix typo 'octects' into 'octets' for asn1.go</li>
<li><a
href="https://github.com/golang/crypto/commit/acbcbef23f9b1b3b7c64673f0ed8baa83475edbe"><code>acbcbef</code></a>
acme: remove unnecessary []byte conversion</li>
<li><a
href="https://github.com/golang/crypto/commit/376eb1400636d0d687bee5520daadb5fdeac3311"><code>376eb14</code></a>
x509roots: support constrained roots</li>
<li><a
href="https://github.com/golang/crypto/commit/b369b723c8ad46b179f3a49d57bfc7d6a2740cdf"><code>b369b72</code></a>
crypto/internal/poly1305: implement function update in assembly on
loong64</li>
<li><a
href="https://github.com/golang/crypto/commit/6b853fbea37a941d918ac0760a5492802df42b9b"><code>6b853fb</code></a>
ssh/knownhosts: check more than one key</li>
<li>See full diff in <a
href="https://github.com/golang/crypto/compare/v0.36.0...v0.37.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/net` from 0.37.0 to 0.38.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/net/commit/e1fcd82abba34df74614020343be8eb1fe85f0d9"><code>e1fcd82</code></a>
html: properly handle trailing solidus in unquoted attribute value in
foreign...</li>
<li><a
href="https://github.com/golang/net/commit/ebed060e8f30f20235f74808c22125fd86b15edd"><code>ebed060</code></a>
internal/http3: fix build of tests with GOEXPERIMENT=nosynctest</li>
<li><a
href="https://github.com/golang/net/commit/1f1fa29e0a46fffe18c43a9da8daa5a0b180dfa9"><code>1f1fa29</code></a>
publicsuffix: regenerate table</li>
<li><a
href="https://github.com/golang/net/commit/12150816f701c912a32a376754ab28dd3878833a"><code>1215081</code></a>
http2: improve error when server sends HTTP/1</li>
<li><a
href="https://github.com/golang/net/commit/312450e473eae9f9e6173ad895c80bc5ea2f79ad"><code>312450e</code></a>
html: ensure &lt;search&gt; tag closes &lt;p&gt; and update tests</li>
<li><a
href="https://github.com/golang/net/commit/09731f9bf919b00b344c763894cd1920b3d96d90"><code>09731f9</code></a>
http2: improve handling of lost PING in Server</li>
<li><a
href="https://github.com/golang/net/commit/55989e24b972a90ab99308fdc7ea1fb58a96fef1"><code>55989e2</code></a>
http2/h2c: use ResponseController for hijacking connections</li>
<li><a
href="https://github.com/golang/net/commit/2914f46773171f4fa13e276df1135bafef677801"><code>2914f46</code></a>
websocket: re-recommend gorilla/websocket</li>
<li>See full diff in <a
href="https://github.com/golang/net/compare/v0.37.0...v0.38.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/oauth2` from 0.28.0 to 0.29.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/oauth2/commit/65c15a35147ccc5127e9f8cdf2e07837596e56b4"><code>65c15a3</code></a>
oauth2: remove extra period</li>
<li><a
href="https://github.com/golang/oauth2/commit/ce56909505b351a755ad0bc294c5ee01ed0ea050"><code>ce56909</code></a>
jws: improve fix for CVE-2025-22868</li>
<li>See full diff in <a
href="https://github.com/golang/oauth2/compare/v0.28.0...v0.29.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/sync` from 0.12.0 to 0.13.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/sync/commit/396f3a06ea2a49eb410f12e244c0dd77095d0de9"><code>396f3a0</code></a>
errgroup: document calling Go before Wait</li>
<li>See full diff in <a
href="https://github.com/golang/sync/compare/v0.12.0...v0.13.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/sys` from 0.31.0 to 0.32.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/sys/commit/01aaa8342f9d6e36356d05d0baff28e64ee6367e"><code>01aaa83</code></a>
all: simplify code by using modern Go constructs</li>
<li><a
href="https://github.com/golang/sys/commit/1b2bd6bb49091efddfc5ca87435bcea9e2090720"><code>1b2bd6b</code></a>
windows: replace all StringToUTF16 calls with UTF16FromString</li>
<li><a
href="https://github.com/golang/sys/commit/1c3b72f1c1fa7f3a3a355c7a963cd1c958135d01"><code>1c3b72f</code></a>
unix: update Linux kernel to 6.14</li>
<li><a
href="https://github.com/golang/sys/commit/c175b6ba6781614eadf22a0727389d97e25f72ee"><code>c175b6b</code></a>
windows: add cmsghdr and pktinfo structures</li>
<li><a
href="https://github.com/golang/sys/commit/3330b5e756f9a4ffd9510bc98b4c8b5b6d05b9c7"><code>3330b5e</code></a>
unix: support Readv, Preadv, Writev and Pwritev for darwin</li>
<li><a
href="https://github.com/golang/sys/commit/7401cce31392295f531e1d0fcc2f01d782353300"><code>7401cce</code></a>
cpu: replace specific instructions with WORD in the function get_cpucfg
on lo...</li>
<li><a
href="https://github.com/golang/sys/commit/b8f7da6c5a244c4015da1e739f7f40b21f4c40c8"><code>b8f7da6</code></a>
cpu: add support for detecting cpu features on loong64</li>
<li><a
href="https://github.com/golang/sys/commit/f2ce62c21a0ddb543d412be19f3168b09d76d1b8"><code>f2ce62c</code></a>
windows: add constants for PMTUD socket options</li>
<li>See full diff in <a
href="https://github.com/golang/sys/compare/v0.31.0...v0.32.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/term` from 0.30.0 to 0.31.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/term/commit/5d2308b09df8e012ed012f73c878253d901b7f56"><code>5d2308b</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="https://github.com/golang/term/commit/e770dddbf5e3084c939760c50ca84c1adee9c4c4"><code>e770ddd</code></a>
x/term: disabling auto-completion around GetPassword()</li>
<li>See full diff in <a
href="https://github.com/golang/term/compare/v0.30.0...v0.31.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 11:59:56 +00:00
Sas Swart 0b2b643ce2 feat: persist prebuild definitions on template import (#16951)
This PR allows provisioners to recognise and report prebuild definitions
to the coder control plane. It also allows the coder control plane to
then persist these to its store.

closes https://github.com/coder/internal/issues/507

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: evgeniy-scherbina <evgeniy.shcherbina.es@gmail.com>
2025-04-07 10:35:28 +02:00
Mathias Fredriksson 074ec2887d test(agent/agentssh): fix test race and improve Windows compat (#17271)
Fixes coder/internal#558
2025-04-07 11:32:37 +03:00
Spike Curtis 59c5bc9bd2 feat: add hostname-suffix option to config-ssh (#17270)
Adds `hostname-suffix` as a Config SSH option that we get from Coderd, and also accept via a CLI flag.

It doesn't actually do anything with this value --- that's for PRs up the stack, since we need the `coder ssh` command to be updated to understand the suffix first.
2025-04-07 12:11:04 +04:00
Spike Curtis 24248736ac feat: add host suffix to /api/v2/deployment/ssh (#17269)
Adds `HostnameSuffix` to ssh config API and deprecates `HostnamePrefix`. We will still support setting and using the prefix for some time.
2025-04-07 11:57:10 +04:00
Spike Curtis 87d9ff0973 feat: add CODER_WORKSPACE_HOSTNAME_SUFFIX (#17268)
Adds deployment option `CODER_WORKSPACE_HOSTNAME_SUFFIX`. This will eventually replace `CODER_SSH_HOSTNAME_PREFIX`, but we will do this slowly and support both for `coder ssh` for some time.

Note that the name is changed to "workspace" hostname, since this suffix will also be used for Coder Connect on Coder Desktop, which is not limited to SSH.
2025-04-07 11:35:47 +04:00
Vincent Vielle 8f665e364a chore: remove notifications beta label (#17263)
Some notifications `beta` label were remaining after the previous PR -
removing it.
2025-04-06 23:50:18 +02:00
Edward Angert f475555d06 docs: document that default GitHub app requires device flow (#17162)
## Issue

Closes #16824

Document that the default GitHub authentication app provided by Coder
requires device flow, and that this behavior cannot be overridden.

## Changes Made

Claude updated the GitHub authentication documentation to:

1. Add a prominent warning in the Default Configuration section
explaining that the default GitHub app requires device flow and ignores
the `CODER_OAUTH2_GITHUB_DEVICE_FLOW` setting
2. Clarify the Device Flow section to indicate that:
   - Device flow is always enabled for the default GitHub app
   - Device flow is optional for custom GitHub OAuth apps
- The `CODER_OAUTH2_GITHUB_DEVICE_FLOW` setting is ignored when using
the default app


[preview](https://coder.com/docs/@16824-github-device-flow/admin/users/github-auth)

<sub>🤖 Generated with [Claude Code](https://claude.ai/code)</sub>

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: M Atif Ali <atif@coder.com>
2025-04-05 21:44:13 -04:00
Aaron Lehmann e9863aba81 fix: log correct error on drpc connection close error (#17265) 2025-04-04 22:09:42 +03:00
dependabot[bot] cfb6d56f62 chore: bump vite from 5.4.16 to 5.4.17 in /site (#17266)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite)
from 5.4.16 to 5.4.17.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v5.4.17</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v5.4.17/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/v5.4.17/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted -->5.4.17 (2025-04-03)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19782">#19782</a>,
fs check with svg and relative paths (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19784">#19784</a>)
(<a
href="https://github.com/vitejs/vite/commit/84b2b46ed129be8215108e789a90adbb33a9c42c">84b2b46</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19782">#19782</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/19784">#19784</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/0a2518a98d2354c61ee8ef51f7d00fa92aebb511"><code>0a2518a</code></a>
release: v5.4.17</li>
<li><a
href="https://github.com/vitejs/vite/commit/84b2b46ed129be8215108e789a90adbb33a9c42c"><code>84b2b46</code></a>
fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19782">#19782</a>,
fs check with svg and relative paths (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19784">#19784</a>)</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite/commits/v5.4.17/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vite&package-manager=npm_and_yarn&previous-version=5.4.16&new-version=5.4.17)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 18:10:01 +00:00
brettkolodny ae7afd1aa0 feat: split cli roles edit command into create and update commands (#17121)
Closes #14239
2025-04-04 14:04:20 -04:00
Jaayden Halko 53af7e1b90 feat: add shadcn radio-group component (#17264)
Based on the Figma designs:
https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=1786-4794&t=EAs4E89RAJLhivNj-1

<img width="127" alt="Screenshot 2025-04-04 at 16 38 14"
src="https://github.com/user-attachments/assets/e4c72fa9-0491-4674-aeb8-ed0ca4a58649"
/>
2025-04-04 14:00:13 -04:00
Charlie Voiselle b000a7a093 docs: update markdown list in scale-coder.md (#17262) 2025-04-04 12:15:13 -04:00
Bruno Quaresma 17664f481e refactor: update provisioners page to match the new design (#17232)
**Demo**


https://github.com/user-attachments/assets/b880326c-7e94-4778-8166-91af7699901e



Closes https://github.com/coder/coder/issues/17221
2025-04-04 12:00:40 -03:00
Jon Ayers 900eb251eb chore: update Terraform to 1.11.3 (#17256)
- Generated with Claude Code
2025-04-04 10:31:45 -04:00
Vincent Vielle 6a624e7476 chore: remove beta tag from notifications (#17251)
Related to [this issue](https://github.com/coder/internal/issues/557)
2025-04-04 16:28:37 +02:00
Jaayden Halko 8a24372e4d feat: add shadcn checkbox component (#17248)
contributes to coder/preview#55

Add shadcn checkbox component matching Figma styles from Coder Kit:
https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=489-4187&t=Zx137ETWsQZtaCku-1

<img width="52" alt="Screenshot 2025-04-03 at 21 15 52"
src="https://github.com/user-attachments/assets/ff2de95c-cb12-46ed-af31-a6d230e52a31"
/>
2025-04-04 10:05:21 -04:00
Jaayden Halko ae67e33c66 fix: set permissions for experimental Createworkspace page (#17254) 2025-04-04 09:59:01 -04:00
Bruno Quaresma 510bc37cbc refactor: update avatar sizes in groups, users and members (#17230)
We updated the template and workspace avatars to be "lg" so to keep it
consistent we have to do the same for the other avatars too.
2025-04-04 10:09:37 -03:00
Bruno Quaresma 3bfafe3b43 feat: add job status filter (#17202)
Closes https://github.com/coder/coder/issues/17155

**Demo:**


https://github.com/user-attachments/assets/fc57e991-c2d5-4712-adac-e072ee7b318d
2025-04-04 10:02:36 -03:00
Edward Angert 43d584c4f3 docs: add a section about latency and how it's measured (#16734)
closes https://github.com/coder/coder/issues/14942

- what latency is measured
- where it's reported
- how users experience latency
- how to lower latency



[preview](https://coder.com/docs/@14942-latency/admin/networking#latency)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-04 08:12:11 -04:00
Spike Curtis 42e5d71f59 fix: fix closeMutex unlock bug (#17259)
Fixes https://github.com/coder/internal/issues/550

Classic return before unlocking bug.
2025-04-04 14:29:56 +04:00
Spike Curtis f6bf6c6ec4 fix!: use names not IDs for agent SSH key seed (#17258)
Changes the SSH host key seeding to use the owner username, workspace name, and agent name. This prevents SSH from complaining about a mismatched host key if you use Coder Desktop to connect, and delete and recreate your workspace with the same name. Previously this would generate a different key because the workspace ID changed.

We also include the owner's username in anticipation of using Coder Desktop to access shared workspaces (or as a superuser) down the road, so that workspaces with the same name owned by different users will not have the same key.

This change is **BREAKING** in a limited sense that early access users of Coder Desktop will see their SSH clients complain about host keys changing the first time each workspace is rebuilt with this code. It can be resolved by clearing your `.ssh/known_hosts` file of the Coder workspaces you access this way.
2025-04-04 12:51:46 +04:00
Jon Ayers 3a0e8ddf97 chore: update esbuild to 0.25.0 (#17214)
- Resolves GHSA-67mh-4wv8-2f99
2025-04-04 02:21:32 -04:00
brettkolodny e64140e999 fix: fix frontend build errors (#17252) 2025-04-03 18:02:39 -04:00
Jaayden Halko 54ff17bec6 feat: create experimental CreateWorkspacePage and dynamic-parameters experiment (#17240)
The purpose of the PR is to make a copy of the CreateWorkspacePage and
create an experimental version that will use when the dynamic-parameters
experiment is enabled.

The Figma designs for this page are still in progress but this first PR
will start to move to the new designs.

Figma design:
https://www.figma.com/design/SMg6H8VKXnPSkE6h9KPoAD/UX-Presets?node-id=2121-2383&t=CtgPUz8eNsTI5b1t-1

Much of the existing code will be left behind and will slowly migrated
over the course of several PRs to make sure no existing functionality is
forgotten in the migration to dynamic paramaters.
2025-04-03 16:39:12 -04:00
Jon Ayers ae44ecfc07 chore: update prismjs to 1.30.0 (#17215)
- Resolves GHSA-x7hr-w5r2-h6wg
2025-04-03 14:13:34 -04:00
Jaayden Halko ccfe1bda1a fix: fix permissions for workspace creation (#17241)
This fixes the permissions check when creating a workspace by setting
the owner_id to the current user's id. This was originally setting
owner_id to *

```
		createWorkspace: {
			object: {
				resource_type: "workspace",
				organization_id: organizationId,
				owner_id: userId,
			},
			action: "create",
		},
```
2025-04-03 11:46:33 -04:00
Mathias Fredriksson b61f0ab958 fix(agent): ensure SSH server shutdown with process groups (#17227)
Fix hanging workspace shutdowns caused by orphaned SSH child processes.
Key changes:

- Create process groups for non-PTY SSH sessions
- Send SIGHUP to entire process group for proper termination
- Add 5-second timeout to prevent indefinite blocking

Fixes #17108
2025-04-03 16:01:43 +03:00
Jaayden Halko b60934b180 chore: hide workspace creation UI for users without permission (#16871)
resolves coder/internal#426
2025-04-03 06:14:25 -04:00
Danielle Maywood ab8c437abc feat(site): open dev container in vscode (#17182)
Closes https://github.com/coder/coder/issues/16426

Adds a new button `VSCodeDevContainerButton` for connecting to a dev
container with VSCode.
2025-04-03 11:10:38 +01:00
Danielle Maywood aa3d71d169 feat(cli): support opening devcontainers in vscode (#17189)
Closes https://github.com/coder/coder/issues/16427

Adds the option `-c,--container` to `open vscode` that allows opening
VSCode into a running devcontainer.
2025-04-03 10:21:23 +01:00
Sas Swart 99c6f235eb feat: add migrations and queries to support prebuilds (#16891)
Depends on https://github.com/coder/coder/pull/16916 _(change base to
`main` once it is merged)_

Closes https://github.com/coder/internal/issues/514

_This is one of several PRs to decompose the `dk/prebuilds` feature
branch into separate PRs to merge into `main`._

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: evgeniy-scherbina <evgeniy.shcherbina.es@gmail.com>
2025-04-03 10:58:30 +02:00
Cian Johnston 4aa45a5c43 fix(cli): modify exp mcp configure to also read claude API key from CLAUDE_API_KEY env (#17229)
Currently you have to set `CODER_MCP_CLAUDE_API_KEY`, which can be
obnoxious.
2025-04-03 09:45:17 +01:00
Ethan 998724de91 chore: sort agent /list-directory output (#17218)
This sorts the `contents` list alphabetically, but with directories before everything else.
This is purely for UX on the Coder Desktop side, where the user only really cares about directories, and files are just for providing context in the file picker.
2025-04-03 12:31:46 +11:00
ケイラ 5979c3224d chore: skip flakey e2e tests (#17235) 2025-04-02 17:38:52 -06:00
ケイラ ac7ea08873 chore: add files cache for reading template tar archives from db (#17141) 2025-04-02 16:42:16 -06:00
dependabot[bot] c06294235f chore: bump next from 14.2.25 to 14.2.26 in /offlinedocs (#17234)
Bumps [next](https://github.com/vercel/next.js) from 14.2.25 to 14.2.26.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/next.js/releases">next's
releases</a>.</em></p>
<blockquote>
<h2>v14.2.26</h2>
<blockquote>
<p>[!NOTE]<br />
This release is backporting bug fixes. It does <strong>not</strong>
include all pending features/changes on canary.</p>
</blockquote>
<h3>Core Changes</h3>
<ul>
<li>Match subrequest handling for edge and node (<a
href="https://redirect.github.com/vercel/next.js/issues/77476">#77476</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/next.js/commit/10a042cdca294fd1c6852b320954bc6ccc6064e7"><code>10a042c</code></a>
v14.2.26</li>
<li><a
href="https://github.com/vercel/next.js/commit/8a511d6a22d38132c79b8f70ee29713d42225802"><code>8a511d6</code></a>
Match subrequest handling for edge and node (<a
href="https://redirect.github.com/vercel/next.js/issues/77476">#77476</a>)</li>
<li>See full diff in <a
href="https://github.com/vercel/next.js/compare/v14.2.25...v14.2.26">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=next&package-manager=npm_and_yarn&previous-version=14.2.25&new-version=14.2.26)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 22:42:01 +00:00
Michael Smith c938bfeaab fix: prevent invalid render output for build logs (#17233)
## Changes made
- Updated `Line` type in `LogLine.tsx` to support an ID value to prevent
key conflicts during React rendering. Also deleted the `LineWithID`
type, which became redundant after the change
- Updated the `Logs` component to use the ID to avoid render key
conflicts
- Updated any component calls to add the ID as a prop

## Notes
- This does prevent a bunch of extra `console.error` calls that React
will automatically spit out, so this should help us a good bit in the
future
- Beyond being a little annoying, there was a chance (that was tiny for
now) that React could accidentally mix up component instances during
re-renders. That wasn't my main goal with this PR (I just wanted less
noisy logs), but that should now be impossible
2025-04-02 17:32:49 -04:00
Edward Angert 0fe7346264 docs: remove enterprise from docs (#17226)
Enterprise is a legacy plan that has been replaced by Premium.

[preview](https://coder.com/docs/@enterprise-feats)

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-02 16:51:57 -04:00
Cian Johnston e8b7ce80de ci: re-enable revive and gosec linters (#17225)
* Reenables revive linter for test files (with an exception for the
`unused-parameter` rule)
* Reenables gosec linter for test files
2025-04-02 16:19:23 +01:00
Spike Curtis 83d7147e02 chore: deprecate ResourceSystem (#17217)
Deprecates `ResourceSystem`. It's a large collection of unrelated things, and violates the principle of least privilege because to get access to low-security stuff like various statistics, you also get access to serious-security stuff like crypto keys.

We should eventually break it up and remove it, but the least we can do for now is not make the problem worse.
2025-04-02 19:17:26 +04:00
Michael Smith ac0cf35591 fix: silence One-Way WebSocket error messages in React Strict Mode (#17204)
## Changes made
- Updated `OneWayWebSocket` class to prevent errors from being
dispatched after a connection has been manually closed.
- Renamed one of the class properties for less ambiguity
- Made error messages for the class constructor more specific
2025-04-02 10:24:05 -04:00
Ben Potter c418e86a4d chore: slightly soften disclaimers for AI features (#17223) 2025-04-02 13:00:06 +00:00
Cian Johnston 0163ddaaee ci: linkspector: fix 403 to external site (#17222) 2025-04-02 13:56:02 +01:00
Ben Potter 13997cacb1 docs: clarify details around MCP (#17220) 2025-04-02 12:48:08 +00:00
Cian Johnston 8cecc4f12d chore(coderd/coderdtest/oidctest): protect mutable fields with rwmutex (#17151)
Protects mutable fields of `FakeIDP` to avoid data races.
2025-04-02 13:36:26 +01:00
Jon Ayers d6c034d2a3 chore: pin dogfood npm dependencies (#17216) 2025-04-02 03:54:49 -04:00
Jon Ayers b1f5d45112 chore: disable e2e-premium tests (#17213)
- These tests are providing no value in their current state due to the
frequency of their intermittent failures.
2025-04-02 07:26:12 +00:00
Ethan 6fdad0272d fix: avoid sharing echo.Responses across tests (#17211)
Closes https://github.com/coder/internal/issues/551

We've noticed lots of flakes in `go test -race` tests that use the echo provisioner. I believe the root cause of this to be https://github.com/coder/coder/pull/17012/, where we started mutating the `echo.Responses`. This only caused issues as we previously shared `echo.Responses` across multiple test cases.

This PR is therefore the same as https://github.com/coder/coder/pull/17128, but I believe this is all the cases where an `echo.Responses` is shared between tests - including tests that haven't flaked (yet).
2025-04-02 13:06:19 +11:00
Jon Ayers d575e7f3ff chore: force babel dependency to 7.26.10 (#17193)
A bunch of dependency issues with babel, it seems forcing an update to
7.26.10 is ok for now
2025-04-01 22:05:23 -04:00
Edward Angert 0ec87abaa5 docs: add new section on managing provisioners from the dashboard (#16563)
closes #16513 


[preview](https://coder.com/docs/@16513-manage-ext-provisioners/admin/provisioners/manage-provisioner-jobs)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-01 21:04:31 -05:00
Edward Angert 0125ff4592 docs: add new workspace notifications dashboard and config (#16548)
closes #16511 


[preview](https://coder.com/docs/@16511-dashboard-vscode-notif/admin/monitoring/notifications)

(beta tag is removed in https://github.com/coder/coder/pull/17096)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-01 21:03:55 -05:00
Edward Angert 2efb8088f4 docs: remove beta badge from notifications doc (#17096)
remove beta from notifications doc


[preview](https://coder.com/docs/@notifications-beta/admin/monitoring/notifications)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-01 21:52:09 -04:00
Benjamin Peinhardt 51ce04780d fix: replace aliased import with unaliased import (#17207)
If you take a look at the comment above, these imports need to be
unaliased.
2025-04-01 20:27:51 -05:00
Asher c6e866225f fix: watch workspace agent logs (#17209) 2025-04-01 17:18:44 -08:00
Ben Potter a61c3e7a1c docs: add tutorials for using early access AI agent features (#17186)
Some content is still being merged, but the structure is still there

Preview: https://coder.com/docs/@ai-features/tutorials/ai-agents
2025-04-01 19:57:05 -05:00
Bruno Quaresma 4604f191e9 refactor: increase workspace and template avatar size (#17200)
**Before**
<img width="1363" alt="Screenshot 2025-04-01 at 14 46 10"
src="https://github.com/user-attachments/assets/d3d76d70-df16-4b27-a138-e493e0bcac83"
/>
<img width="1360" alt="Screenshot 2025-04-01 at 14 45 55"
src="https://github.com/user-attachments/assets/bbae38fe-6ed2-42fa-99b0-e24f6c8d382d"
/>

**After**
<img width="1359" alt="Screenshot 2025-04-01 at 14 46 18"
src="https://github.com/user-attachments/assets/230b606b-fd5f-4e42-9ca2-56ddb2e1f617"
/>
<img width="1362" alt="Screenshot 2025-04-01 at 14 46 02"
src="https://github.com/user-attachments/assets/b22d4b59-4660-47dd-a362-e8d842dd2a82"
/>
2025-04-01 21:29:36 -03:00
Stephen Kirby a3248f9364 chore(docs): move feature stage docs to install directory (#17199)
I think the feature stages page should be co-located with releases and
not at the entrance of the docs.


[preview](https://coder.com/docs/@move-feature-stages/install/releases/feature-stages)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-04-01 18:44:51 -05:00
ケイラ 184c1f0a59 chore: add db queries for dynamic parameters (#17137) 2025-04-01 15:47:30 -06:00
Ben Potter fd241164a9 docs: clarify that CODER_EXTERNAL_AUTH_0_ID is used in callback URLs (#16879)
## Summary
- Clarifies that the CODER_EXTERNAL_AUTH_0_ID value is used as part of
the OAuth callback URL path
- Adds explicit callback URL examples to GitLab and Bitbucket Server
sections
- Updates the GitHub OAuth app configuration instructions to be more
explicit
- Fixes the documentation mistake where it claimed this ID was only for
"internal reference"

## Test plan
- Documentation change only
- Verified consistency across all OAuth provider sections

Fixes #16851


[preview](https://coder.com/docs/@fix-external-auth-docs-16851/admin/external-auth)

<sub>🤖 Generated with [Claude Code](https://claude.ai/code)</sub>

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Edward Angert <EdwardAngert@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
2025-04-01 17:03:25 -04:00
Sas Swart 00e1ea4ccf feat: add the ability to hide preset parameters (#17168)
This PR adds the ability to hide presets on the workspace creation form.
When showing them, a clear indication is now made as to which inputs
were preset and which weren't.


![image](https://github.com/user-attachments/assets/6c8f690c-7cf6-44a9-9657-65039b2b3cb7)
2025-04-01 22:51:42 +02:00
Cian Johnston 88bae05223 feat(cli): implement exp mcp configure claude-code command (#17195)
Updates `~/.claude.json` and `~/.claude/CLAUDE.md` with required
settings for agentic usage.
2025-04-01 20:06:42 +01:00
Kyle Carberry f3e5bb9276 fix: convert workspace id in db2sdk.WorkspaceAppStatus (#17201)
This was causing no status to be rendered in the list, and
`latest_app_status` to always be nil.
2025-04-01 14:49:32 -04:00
Edward Angert 900e125e4a docs: update SMTP configuration in notifications docs (#17161)
## Issue

Closes #16206

(thanks @bjornrobertsson - not sure why I can't tag you as a reviewer)

Mismatch between the SMTP configuration UI and the documentation.

## Verification

Claude verified this issue by examining:

1. The current SMTP configuration code in the codebase
2. The CLI help documentation for the server command
3. The examples provided in the notifications documentation

The issue was confirmed by finding:
- A reference to a deprecated variable
`CODER_NOTIFICATIONS_EMAIL_FORCE_TLS` instead of the current
`CODER_EMAIL_FORCE_TLS`
- Missing information about the port format required for the SMTP
smarthost

## Changes made

1. Updated the `--email-smarthost` description to clarify that the
format should include both hostname and port: `(format:
     hostname:port)`
2. Fixed the reference to the TLS environment variable in the STARTTLS
description, replacing the deprecated
`CODER_NOTIFICATIONS_EMAIL_FORCE_TLS` with the correct
`CODER_EMAIL_FORCE_TLS`

## Additional information

The Gmail and Outlook examples in the documentation already correctly
show the port included in the smarthost configuration, but the main
description table needed to be updated to explicitly mention this
requirement.


[preview](https://coder.com/docs/@16206-smtp-required-components/admin/monitoring/notifications)

<sub>🤖 Generated with [Claude Code](https://claude.ai/code)</sub>

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-01 14:44:09 -04:00
Kyle Carberry 583a0c652f feat: add frontend for app statuses (#17178)
Check out the stories for the exacts...


![image](https://github.com/user-attachments/assets/a1e1b9b0-7b37-4e0d-b99e-64b4766519ef)


![image](https://github.com/user-attachments/assets/d3eb580d-071c-4caf-b393-a7e87da61f5e)
2025-04-01 12:35:58 -04:00
Cian Johnston 27d2343adf fix(cli): exp mcp: remove unnecessary cli flag (#17190) 2025-04-01 16:53:18 +01:00
Edward Angert 037dbc84da docs: add new cursor and windsurf docs (#17092)
closes #16919 

- [x] cursor doc
- [x] windsurf doc

from
https://github.com/coder/coder/issues/16919#issuecomment-2737033477:
- add to access-workspace
- link to module(s)
- how to windsurf with ssh
- temp: install vsix manually (Windsurf)
   - from <https://github.com/coder/vscode-coder>
- log in first
- search extensions for Coder
- ask your admin to add a module:
https://registry.coder.com/modules/cursor

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
2025-04-01 20:13:32 +05:00
Michael Smith fcac4abcca fix(site): standardize headers for Admin Settings page (#16911)
## Changes made
- Switched almost all headers to use the `SettingHeader` component
- Redesigned component to be more composition-based, to stay in line
with the patterns we're starting to use more throughout the codebase
- Refactored `SettingHeader` to be based on Radix and Tailwind, rather
than Emotion/MUI
- Added additional props to `SettingHeader` to help resolve issues with
the component creating invalid HTML
- Beefed up `SettingHeader` to have better out-of-the-box accessibility
- Addressed some typographic problems in `SettingHeader`
- Addressed some responsive layout problems for `SettingsHeader`
- Added first-ever stories for `SettingsHeader`

## Notes
- There are still a few headers that aren't using `SettingHeader` yet.
There were some UI edge cases that meant I couldn't reliably bring it in
without consulting the Design team first. I'm a little less worried
about them, because they at least *look* like the other headers, but
it'd be nice if we could centralize everything in a followup PR
2025-04-01 10:13:56 -04:00
Cian Johnston 1e11e823c9 fix(mcp): report task status correctly (#17187) 2025-04-01 15:02:08 +01:00
Ethan 3a243c111b fix: remove shared mutable state between oidc tests (#17179)
Spotted on main: https://github.com/coder/coder/actions/runs/14179449567/job/39721999486
```
=== FAIL: coderd TestOIDCDomainErrorMessage/MalformedEmailErrorOmitsDomains (0.01s)
==================
WARNING: DATA RACE
Read at 0x00c060b54e68 by goroutine 296485:
  golang.org/x/oauth2.(*Config).Exchange()
      /home/runner/go/pkg/mod/golang.org/x/oauth2@v0.28.0/oauth2.go:228 +0x1d8
  github.com/coder/coder/v2/coderd.(*OIDCConfig).Exchange()
      <autogenerated>:1 +0xb7
  github.com/coder/coder/v2/coderd.New.func11.12.1.2.ExtractOAuth2.1.1()
      /home/runner/work/coder/coder/coderd/httpmw/oauth2.go:168 +0x7b5
  net/http.HandlerFunc.ServeHTTP()
      /opt/hostedtoolcache/go/1.24.1/x64/src/net/http/server.go:2294 +0x47
[...]
Previous write at 0x00c060b54e68 by goroutine 55730:
  github.com/coder/coder/v2/coderd/coderdtest/oidctest.(*FakeIDP).SetRedirect()
      /home/runner/work/coder/coder/coderd/coderdtest/oidctest/idp.go:1280 +0x1e6
  github.com/coder/coder/v2/coderd/coderdtest/oidctest.(*FakeIDP).LoginWithClient()
      /home/runner/work/coder/coder/coderd/coderdtest/oidctest/idp.go:494 +0x170
  github.com/coder/coder/v2/coderd/coderdtest/oidctest.(*FakeIDP).AttemptLogin()
      /home/runner/work/coder/coder/coderd/coderdtest/oidctest/idp.go:479 +0x624
  github.com/coder/coder/v2/coderd_test.TestOIDCDomainErrorMessage.func3()
      /home/runner/work/coder/coder/coderd/userauth_test.go:2041 +0x1f2
```

As seen, this race was caused by sharing a `*oidctest.FakeIDP` between test cases. The fix is to simply do the setup twice.

```
$ go test -race -run "TestOIDCDomainErrorMessage" github.com/coder/coder/v2/coderd -count=100
ok      github.com/coder/coder/v2/coderd        7.551s
````
2025-04-01 22:28:05 +11:00
Hugo Dutka 7d08bf0afe chore: improve error logging in TestServer/EphemeralDeployment (#17184)
There's a flake reported in https://github.com/coder/internal/issues/549
that was caused by the built-in Postgres failing to start. However, the
test was written in a way that didn't log the actual error which caused
Postgres to fail. This PR improves error logging in the affected test so
that the next time the error happens, we know what it is.
2025-04-01 13:23:06 +02:00
Cian Johnston e4cf18989c chore(mcp): fix test flakes (#17183)
Closes https://github.com/coder/internal/issues/547
2025-04-01 11:28:47 +01:00
Cian Johnston cc733aba71 ci: check go versions are consistent (#17149)
Fixes https://github.com/coder/coder/issues/17063

I'm ignoring flake.nix for now.

```
$ IGNORE_NIX=true ./scripts/check_go_versions.sh
INFO : go.mod                   : 1.24.1
INFO : dogfood/coder/Dockerfile : 1.24.1
INFO : setup-go/action.yaml     : 1.24.1
INFO : flake.nix                : 1.22
INFO : Ignoring flake.nix, as IGNORE_NIX=true
Go version check passed, all versions are 1.24.1

$ ./scripts/check_go_versions.sh
INFO : go.mod                   : 1.24.1
INFO : dogfood/coder/Dockerfile : 1.24.1
INFO : setup-go/action.yaml     : 1.24.1
INFO : flake.nix                : 1.22
ERROR: Go version mismatch between go.mod and flake.nix
```
2025-04-01 09:03:54 +01:00
Jon Ayers 989c3ec62e chore: pin various dependencies in CI files (#17180) 2025-04-01 00:15:15 -04:00
Jon Ayers 83405677bf chore: pin goimports to 0.31.0 (#17177) 2025-03-31 22:56:21 -04:00
Jon Ayers 7b14b4f5e1 chore: update msw to 2.4.8 (#17167)
- Fixes a transitive vuln in path-to-regexp
2025-03-31 15:10:00 -04:00
dependabot[bot] 40de51b188 chore: bump vite from 5.4.15 to 5.4.16 in /site (#17176)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite)
from 5.4.15 to 5.4.16.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v5.4.16</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted -->5.4.16 (2025-03-31)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19761">#19761</a>,
fs check in transform middleware (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19762">#19762</a>)
(<a
href="https://github.com/vitejs/vite/commit/b627c50d359f3bd9b602408fbbf462cf4a2f019c">b627c50</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19761">#19761</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/19762">#19762</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/712cb71aa0e2a03dbf49db92043fb4ecbfc826b1"><code>712cb71</code></a>
release: v5.4.16</li>
<li><a
href="https://github.com/vitejs/vite/commit/b627c50d359f3bd9b602408fbbf462cf4a2f019c"><code>b627c50</code></a>
fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19761">#19761</a>,
fs check in transform middleware (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19762">#19762</a>)</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite/commits/v5.4.16/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vite&package-manager=npm_and_yarn&previous-version=5.4.15&new-version=5.4.16)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 18:02:30 +00:00
Cian Johnston 057cbd4d80 feat(cli): add coder exp mcp command (#17066)
Adds a `coder exp mcp` command which will start a local MCP server
listening on stdio with the following capabilities:
* Show logged in user (`coder whoami`)
* List workspaces (`coder list`)
* List templates (`coder templates list`)
* Start a workspace (`coder start`)
* Stop a workspace (`coder stop`)
* Fetch a single workspace (no direct CLI analogue)
* Execute a command inside a workspace (`coder exp rpty`)
* Report the status of a task (currently a no-op, pending task support)

This can be tested as follows:

```
# Start a local Coder server.
./scripts/develop.sh
# Start a workspace. Currently, creating workspaces is not supported.
./scripts/coder-dev.sh create -t docker --yes
# Add the MCP to your Claude config.
claude mcp add coder ./scripts/coder-dev.sh exp mcp
# Tell Claude to do something Coder-related. You may need to nudge it to use the tools.
claude 'start a docker workspace and tell me what version of python is installed'
```
2025-03-31 18:52:09 +01:00
Kyle Carberry 8ea956fc11 feat: add app status tracking to the backend (#17163)
This does ~95% of the backend work required to integrate the AI work.

Most left to integrate from the tasks branch is just frontend, which
will be a lot smaller I believe.

The real difference between this branch and that one is the abstraction
-- this now attaches statuses to apps, and returns the latest status
reported as part of a workspace.

This change enables us to have a similar UX to in the tasks branch, but
for agents other than Claude Code as well. Any app can report status
now.
2025-03-31 10:55:44 -04:00
Bruno Quaresma 489641d0be feat: set icons for each type of notification (#17115)
Each notification type will have an icon to represent the context:

<img width="503" alt="Screenshot 2025-03-26 at 13 44 35"
src="https://github.com/user-attachments/assets/1187c1c0-1043-4a32-b105-a7f91b52f8ca"
/>

This depends on https://github.com/coder/coder/pull/17013
2025-03-31 09:40:24 -03:00
Michael Smith 9bc727e977 chore: add support for one-way websockets to backend (#16853)
Closes https://github.com/coder/coder/issues/16775

## Changes made
- Added `OneWayWebSocket` function that establishes WebSocket
connections that don't allow client-to-server communication
- Added tests for the new function
- Updated API endpoints to make new WS-based endpoints, and mark
previous SSE-based endpoints as deprecated
- Updated existing SSE handlers to use the same core logic as the new WS
handlers

## Notes
- Frontend changes handled via #16855
2025-03-28 17:13:20 -04:00
dependabot[bot] d3050a7e77 chore: bump github.com/prometheus/common from 0.62.0 to 0.63.0 (#16959)
Bumps
[github.com/prometheus/common](https://github.com/prometheus/common)
from 0.62.0 to 0.63.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/prometheus/common/releases">github.com/prometheus/common's
releases</a>.</em></p>
<blockquote>
<h2>v0.63.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Making the map a public variable for promtheus-operator by <a
href="https://github.com/dongjiang1989"><code>@​dongjiang1989</code></a>
in <a
href="https://redirect.github.com/prometheus/common/pull/741">prometheus/common#741</a></li>
<li>setup ossf scorecard and codeql workflows by <a
href="https://github.com/mmorel-35"><code>@​mmorel-35</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/564">prometheus/common#564</a></li>
<li>feat(promslog): implement reserved keys, rename duplicates by <a
href="https://github.com/tjhop"><code>@​tjhop</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/746">prometheus/common#746</a></li>
<li>Bump golang.org/x/oauth2 from 0.24.0 to 0.25.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/750">prometheus/common#750</a></li>
<li>Bump golang.org/x/net from 0.33.0 to 0.34.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/749">prometheus/common#749</a></li>
<li>Bump google.golang.org/protobuf from 1.36.1 to 1.36.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/751">prometheus/common#751</a></li>
<li>promslog: Make AllowedLevel concurrency safe. by <a
href="https://github.com/bwplotka"><code>@​bwplotka</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/754">prometheus/common#754</a></li>
<li>Fix typo 'the an' by <a
href="https://github.com/petern48"><code>@​petern48</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/752">prometheus/common#752</a></li>
<li>Synchronize common files from prometheus/prometheus by <a
href="https://github.com/prombot"><code>@​prombot</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/757">prometheus/common#757</a></li>
<li>build(deps): bump google.golang.org/protobuf from 1.36.3 to 1.36.4
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/prometheus/common/pull/756">prometheus/common#756</a></li>
<li>build(deps): bump google.golang.org/protobuf from 1.36.4 to 1.36.5
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/prometheus/common/pull/761">prometheus/common#761</a></li>
<li>build(deps): bump github.com/google/go-cmp from 0.6.0 to 0.7.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/763">prometheus/common#763</a></li>
<li>build(deps): bump golang.org/x/net from 0.34.0 to 0.35.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/762">prometheus/common#762</a></li>
<li>model: Clarify the purpose of model.NameValidationScheme by <a
href="https://github.com/ywwg"><code>@​ywwg</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/765">prometheus/common#765</a></li>
<li>Fix spelling mistake in godoc by <a
href="https://github.com/grobinson-grafana"><code>@​grobinson-grafana</code></a>
in <a
href="https://redirect.github.com/prometheus/common/pull/766">prometheus/common#766</a></li>
<li>Synchronize common files from prometheus/prometheus by <a
href="https://github.com/prombot"><code>@​prombot</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/767">prometheus/common#767</a></li>
<li>otlptranslator: Add dependency free package that translates OTLP
data into Prometheus metric/label names by <a
href="https://github.com/ArthurSens"><code>@​ArthurSens</code></a> in <a
href="https://redirect.github.com/prometheus/common/pull/768">prometheus/common#768</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/dongjiang1989"><code>@​dongjiang1989</code></a>
made their first contribution in <a
href="https://redirect.github.com/prometheus/common/pull/741">prometheus/common#741</a></li>
<li><a href="https://github.com/petern48"><code>@​petern48</code></a>
made their first contribution in <a
href="https://redirect.github.com/prometheus/common/pull/752">prometheus/common#752</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/prometheus/common/compare/v0.62.0...v0.63.0">https://github.com/prometheus/common/compare/v0.62.0...v0.63.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/prometheus/common/commit/cf3c56f7b7d09d67cb46592c5e930651fd2d296e"><code>cf3c56f</code></a>
Merge pull request <a
href="https://redirect.github.com/prometheus/common/issues/768">#768</a>
from prometheus/otlp-translator</li>
<li><a
href="https://github.com/prometheus/common/commit/b35ad995d20d280cd0bc1a30386a4e3bbdc032f5"><code>b35ad99</code></a>
Add test case for BuildCompliantMetricName with a metric that starts
with a d...</li>
<li><a
href="https://github.com/prometheus/common/commit/227989ceacbb831801f90965ed5e8c9c55749774"><code>227989c</code></a>
otlptranslator: Add dependency free package that translator OTLP data
into Pr...</li>
<li><a
href="https://github.com/prometheus/common/commit/a9cc7f7df30d52a26a3937c9d32953ef2bf452c6"><code>a9cc7f7</code></a>
Update common Prometheus files (<a
href="https://redirect.github.com/prometheus/common/issues/767">#767</a>)</li>
<li><a
href="https://github.com/prometheus/common/commit/0decf1fe7a23d909d3f5cd400b76b6d178eef576"><code>0decf1f</code></a>
Fix spelling mistake in godoc (<a
href="https://redirect.github.com/prometheus/common/issues/766">#766</a>)</li>
<li><a
href="https://github.com/prometheus/common/commit/6b9636ca14ecb6f8bb49d70aea6019c4cef93aab"><code>6b9636c</code></a>
model: Clarify the purpose of model.NameValidationScheme (<a
href="https://redirect.github.com/prometheus/common/issues/765">#765</a>)</li>
<li><a
href="https://github.com/prometheus/common/commit/56f6f3853a55cff5c626bc5a04993b3871ff260c"><code>56f6f38</code></a>
build(deps): bump golang.org/x/net from 0.34.0 to 0.35.0 (<a
href="https://redirect.github.com/prometheus/common/issues/762">#762</a>)</li>
<li><a
href="https://github.com/prometheus/common/commit/b516f6d622f0d210e24036fe64e2009fcc44885f"><code>b516f6d</code></a>
build(deps): bump github.com/google/go-cmp from 0.6.0 to 0.7.0 (<a
href="https://redirect.github.com/prometheus/common/issues/763">#763</a>)</li>
<li><a
href="https://github.com/prometheus/common/commit/0db99daa6f43d55a09dbb714fe3173182977bf8f"><code>0db99da</code></a>
build(deps): bump google.golang.org/protobuf from 1.36.4 to 1.36.5 (<a
href="https://redirect.github.com/prometheus/common/issues/761">#761</a>)</li>
<li><a
href="https://github.com/prometheus/common/commit/ca40aa08f025cc1a857cec6d6773363e959b4ea4"><code>ca40aa0</code></a>
build(deps): bump google.golang.org/protobuf from 1.36.3 to 1.36.4 (<a
href="https://redirect.github.com/prometheus/common/issues/756">#756</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/prometheus/common/compare/v0.62.0...v0.63.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/prometheus/common&package-manager=go_modules&previous-version=0.62.0&new-version=0.63.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Muhammad Atif Ali <atif@coder.com>
2025-03-28 20:10:06 +00:00
Jon Ayers 562a6c9ce0 chore: add .cursorrules config (#17160) 2025-03-28 19:33:13 +00:00
Mathias Fredriksson ac74c65fd7 test(cli): fix data race in TestCreateWithRichParameters (#17128)
Shared echo provisioner responses were being mutated simultaneously,
this change fixes it.
2025-03-28 14:02:58 +00:00
Cian Johnston a9574fb4b1 chore(cli): increase timeout for TestSSH_Container subtests (#17148)
Closes https://github.com/coder/internal/issues/524
2025-03-28 13:52:13 +00:00
Edward Angert c6799911dd docs: edit workspace lifecycle description (#17146)
thanks for pointing this out, @jmshoffs0812 !
2025-03-28 07:24:33 -04:00
Vincent Vielle 148dae1e9f fix: add fallback icons for notifications (#17013)
Related: https://github.com/coder/internal/issues/522
2025-03-28 12:21:48 +01:00
ケイラ ca414b031a fix: fix data race in echo provisioner (#17142) 2025-03-27 18:04:05 -06:00
Jon Ayers 1360bfe60d chore: fix false positives in CodeQL for TS (#17139)
Fixes some false positives flagged by CodeQL
2025-03-27 16:09:53 -05:00
Jon Ayers eded0ed4b6 chore: fix false positives in CodeQL (#17138)
Clears up some false positives being surfaced by CodeQL
2025-03-27 16:06:58 -05:00
Cian Johnston e1f27a7137 feat(site): add webpush notification serviceworker (#17123)
* Improves tests for webpush notifications
* Sets subscriber correctly in web push payload (without this,
notifications do not work in Safari)
* NOTE: for now, I'm using the Coder Access URL. Some push messaging
service don't like it when you use a non-HTTPS URL, so dropping a warn
log about this.
* Adds a service worker and context for push notifications
* Adds a button beside "Inbox" to enable / disable push notifications

Notes:
*  Tested in in Firefox and Safari, and Chrome.
2025-03-27 17:30:25 +00:00
Phorcys 661ed2376a chore(examples/templates): add ec2:DescribeInstanceStatus to permissions (#17134)
([Discord
message](https://discord.com/channels/747933592273027093/991429648200245358/1352357113204314173))

---

One of our community users has mentioned needing to add the
`ec2:DescribeInstanceStatus` to permissions.

From the [API
docs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstanceStatus.html):
> Describes the status of the specified instances or all of your
instances

I think it's sensible to add it to our README example for the aws-*
templates, it's probably required now due to changes in either the AWS
API or Terraform provider, and shouldn't have a big impact.
2025-03-27 15:06:50 +00:00
Bruno Quaresma 3e64dcefaf chore: upgrade msw to 2.4.3 (#17135)
Fixes a transitive High severity dependency in path-to-regexp. 

We've tried to [upgrade to
2.5.0](https://github.com/coder/coder/pull/17124) (currently, the latest
version) but there are some known bugs related to polyfills as [this
one](https://github.com/mswjs/msw/discussions/2288). As shared in the
comments, the latest version without this issue is 2.4.3.
2025-03-27 12:00:54 -03:00
Bruno Quaresma 2b59cfa7c5 refactor: add nice enter animation for notification badge (#17119) 2025-03-27 11:43:44 -03:00
Eric Paulsen 5bd2a3f190 fix: conceal sensitive domain information in auth error messages (#17132)
## Summary
- Removes exposure of allowed domain list in OIDC authentication error
messages
- Replaces detailed error messages with a generic message that doesn't
expose internal domains
- Adds "Please contact your administrator" to guide users seeking
assistance
- Addresses security concern where third-party contractors could see
internal domain information

## Test plan
- Test accessing Coder with an email that doesn't match allowed domains
- Verify error message no longer displays the list of authorized domains
- Verify message now includes guidance to contact administrator

Fixes issue related to domain information exposure during
authentication. Linked issue:
https://github.com/coder/coder/issues/17130

🤖 Generated with [Claude Code](https://claude.ai/code)
2025-03-27 13:41:01 +00:00
Michael Vincent Patterson 0eec78d714 feat(cli): push dynamically generated templates with version name (#17114)
Closes #17031 
Updated tempatespush.go
2025-03-27 09:09:46 -04:00
Mathias Fredriksson 7d4b3c8634 feat(agent): add devcontainer autostart support (#17076)
This change adds support for devcontainer autostart in workspaces. The
preconditions for utilizing this feature are:

1. The `coder_devcontainer` resource must be defined in Terraform
2. By the time the startup scripts have completed,
	- The `@devcontainers/cli` tool must be installed
	- The given workspace folder must contain a devcontainer configuration

Example Terraform:

```tf
resource "coder_devcontainer" "coder" {
  agent_id         = coder_agent.main.id
  workspace_folder = "/home/coder/coder"
  config_path      = ".devcontainer/devcontainer.json" # (optional)
}
```

Closes #16423
2025-03-27 12:31:30 +02:00
dependabot[bot] 2ba3d77c74 chore: bump github.com/golang-jwt/jwt/v5 from 5.2.1 to 5.2.2 (#17126)
Bumps [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt)
from 5.2.1 to 5.2.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/golang-jwt/jwt/releases">github.com/golang-jwt/jwt/v5's
releases</a>.</em></p>
<blockquote>
<h2>v5.2.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Fixed <a
href="https://github.com/golang-jwt/jwt/security/advisories/GHSA-mh63-6h87-95cp">https://github.com/golang-jwt/jwt/security/advisories/GHSA-mh63-6h87-95cp</a>
by <a
href="https://github.com/mfridman"><code>@​mfridman</code></a></li>
<li>Fixed some typos by <a
href="https://github.com/Ashikpaul"><code>@​Ashikpaul</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/382">golang-jwt/jwt#382</a></li>
<li>build: add go1.22 to ci workflows by <a
href="https://github.com/mfridman"><code>@​mfridman</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/383">golang-jwt/jwt#383</a></li>
<li>Bump golangci/golangci-lint-action from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/387">golang-jwt/jwt#387</a></li>
<li>Bump golangci/golangci-lint-action from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/389">golang-jwt/jwt#389</a></li>
<li>chore: bump ci tests to include go1.23 by <a
href="https://github.com/mfridman"><code>@​mfridman</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/405">golang-jwt/jwt#405</a></li>
<li>Fix jwt -show by <a
href="https://github.com/AlexanderYastrebov"><code>@​AlexanderYastrebov</code></a>
in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/406">golang-jwt/jwt#406</a></li>
<li>docs: typo by <a
href="https://github.com/kvii"><code>@​kvii</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/407">golang-jwt/jwt#407</a></li>
<li>Update SECURITY.md by <a
href="https://github.com/oxisto"><code>@​oxisto</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/416">golang-jwt/jwt#416</a></li>
<li>Update <code>jwt.Parse</code> example to use
<code>jwt.WithValidMethods</code> by <a
href="https://github.com/mattt"><code>@​mattt</code></a> in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/425">golang-jwt/jwt#425</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Ashikpaul"><code>@​Ashikpaul</code></a>
made their first contribution in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/382">golang-jwt/jwt#382</a></li>
<li><a href="https://github.com/kvii"><code>@​kvii</code></a> made their
first contribution in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/407">golang-jwt/jwt#407</a></li>
<li><a href="https://github.com/mattt"><code>@​mattt</code></a> made
their first contribution in <a
href="https://redirect.github.com/golang-jwt/jwt/pull/425">golang-jwt/jwt#425</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/golang-jwt/jwt/compare/v5.2.1...v5.2.2">https://github.com/golang-jwt/jwt/compare/v5.2.1...v5.2.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang-jwt/jwt/commit/0951d184286dece21f73c85673fd308786ffe9c3"><code>0951d18</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/c035977d9e11c351f4c05dfeae193923cbab49ee"><code>c035977</code></a>
Update Parse example to use WithValidMethods (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/425">#425</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/bc8bdca5cced1caa9787e4a1c313a3538544c877"><code>bc8bdca</code></a>
Update SECURITY.md (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/416">#416</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/5ec246c074b71790eec1f2e05b54daf6ec29ec5f"><code>5ec246c</code></a>
docs: typo (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/407">#407</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/0123f1ad66cbc45013dbfba6eff0cd81472bfc12"><code>0123f1a</code></a>
Fix jwt -show (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/406">#406</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/f961c72abd3b91442a9ab3d3e356bf547636e89b"><code>f961c72</code></a>
chore: bump ci tests to include go1.23 (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/405">#405</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/62e504c2810b67f6b97313424411cfffb25e41b0"><code>62e504c</code></a>
Bump golangci/golangci-lint-action from 5 to 6 (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/389">#389</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/1a56dcf532089fc2bb723a3cb4076a4e45cb1c1a"><code>1a56dcf</code></a>
Bump golangci/golangci-lint-action from 4 to 5 (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/387">#387</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/c8043eab61f0ec5bdd924c1c30caf164a9bb2c66"><code>c8043ea</code></a>
build: add go1.22 to ci workflows (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/383">#383</a>)</li>
<li><a
href="https://github.com/golang-jwt/jwt/commit/7c3f6dc56316e5e222a9df9612ec04243189a989"><code>7c3f6dc</code></a>
Update README.md (<a
href="https://redirect.github.com/golang-jwt/jwt/issues/382">#382</a>)</li>
<li>See full diff in <a
href="https://github.com/golang-jwt/jwt/compare/v5.2.1...v5.2.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/golang-jwt/jwt/v5&package-manager=go_modules&previous-version=5.2.1&new-version=5.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 10:29:44 +00:00
Cian Johnston 06e5d9ef21 feat(coderd): add webpush package (#17091)
* Adds `codersdk.ExperimentWebPush` (`web-push`)
* Adds a `coderd/webpush` package that allows sending native push
notifications via `github.com/SherClockHolmes/webpush-go`
* Adds database tables to store push notification subscriptions.
* Adds an API endpoint that allows users to subscribe/unsubscribe, and
send a test notification (404 without experiment, excluded from API docs)
* Adds server CLI command to regenerate VAPID keys (note: regenerating
the VAPID keypair requires deleting all existing subscriptions)

---------

Co-authored-by: Kyle Carberry <kyle@carberry.com>
2025-03-27 10:03:53 +00:00
Cian Johnston 006600ea3e chore(enterprise/dbcrypt): adjust behaviour of TestHelpMeEncryptSomeValue (#17116)
This "utility test" isn't so useful if you have to uncomment the
`t.Skip()` before using it.
2025-03-27 09:45:34 +00:00
Cian Johnston 0d8d5f212a chore: linkspector: ignore 503s from docs.github.com (#17125)
Fixes a 503 seen here:
https://github.com/coder/coder/actions/runs/14094256166/job/39478147255?pr=17091
2025-03-27 09:13:24 +00:00
Cian Johnston b863eca196 fix(scripts/check_unstaged.sh): add argument separator in git diff command (#17122) 2025-03-27 08:57:12 +00:00
Jon Ayers 2dc99c8469 fix: correct spurious edits made during the lint fixing slog (#17113) 2025-03-27 01:13:21 -05:00
Edward Angert 6bb4bdb9cb docs: add troubleshooting section to Desktop docs (#17098)
[preview](https://coder.com/docs/@121-desktop-troubleshoot/user-guides/desktop)

relates to https://github.com/coder/coder-desktop-macos/issues/121

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
2025-03-26 19:00:32 +00:00
Cian Johnston d7a81f1d9b chore(dogfood): add lsof (#17117)
because lsof is a standard linux utility
2025-03-26 18:58:03 +00:00
Vincent Vielle ddb06741c9 chore: improve dormant workspace notification wording (#17100)
Related to #17099
2025-03-26 15:54:03 +01:00
Danielle Maywood cac130346d chore: bump debounce from 5 minutes to 30 minutes (#17111)
To ensure OOM/OOD isn't too spammy we want to have a debounce period of
30 minutes.
2025-03-26 14:33:10 +00:00
Bruno Quaresma 9668cba0e5 refactor: improve markdown rendering on notifications (#17112)
**Before:**
<img width="753" alt="Screenshot 2025-03-26 at 11 11 46"
src="https://github.com/user-attachments/assets/d4504de9-d007-43bf-9e0b-a8ff1b04da2c"
/>

**After:**

![image](https://github.com/user-attachments/assets/5a249a48-e2ec-4573-97ea-7a978fbe3c9a)
2025-03-26 11:24:54 -03:00
Danielle Maywood eaab4045f5 fix: prevent password reset notifications ending up in coder inbox (#17109) 2025-03-26 12:19:14 +01:00
Mathias Fredriksson 310f148cb4 fix(dogfood/coder): add shutdown script and graceful agent shutdown (#17110)
By stopping Docker, we can hopefully avoid errors like this:

```
2025-03-26 12:14:53.280+02:00 Error: Error deleting container aa313fca0f72e59d4571afec898392e0ae34567d56c0ad15554c87394d2ca1e1: Error response from daemon: container aa313fca0f72e59d4571afec898392e0ae34567d56c0ad15554c87394d2ca1e1: driver "overlay2" failed to remove root filesystem: unlinkat /var/data/docker/overlay2/2e8e509237c79ebec972cccae9867f3bd6f71d49d4ed68db1b5ba229c3a2ff62/diff/var/lib/docker/overlay2/9c7c4ab0187ece1ca270d146090a8e852808996279d103cb394b2821c472af4c/diff/usr/lib/python3/dist-packages/ansible_collections: directory not empty
```
2025-03-26 13:17:51 +02:00
Danielle Maywood c8f3b35e13 fix: prevent password reset notifications ending up in coder inbox (#17109)
We do not want password reset notifications to end up in Coder Inbox as
this doesn't make much sense. This implements the logic to ensure they
are not delivered if the method is Coder Inbox.

In the future we might want to investigate a better solution but for now
this works.
2025-03-26 11:08:31 +00:00
Danielle Maywood 1bbbae8d57 chore: migrate to github.com/coder/clistat (#17107)
Migrate from in-tree `clistat` package to
https://github.com/coder/clistat.
2025-03-26 10:36:53 +00:00
Cian Johnston 811097ef03 chore(dogfood): update dogfood Go version to 1.24.1 (#17104)
https://github.com/coder/coder/pull/17035 updated the Go version in
`go.mod` and in GH actions but not in `dogfood/coder/Dockerfile` or
`flake.nix`.

This updates the Go version to 1.24 in `dogfood/coder/Dockerfile`.
Unfortunately at the time of writing, Go 1.24 is not available in NixOS.
So that will have to wait.
2025-03-26 10:32:43 +00:00
Spike Curtis f6a10eeb7f chore: sync vpn.proto with coder/coder-desktop-windows (#17106)
Syncs `vpn.proto` with https://github.com/coder/coder-desktop-windows/blob/main/Vpn.Proto/vpn.proto
2025-03-26 13:38:39 +04:00
dependabot[bot] b4fa8097ef chore: bump the x group across 1 directory with 2 updates (#17103)
Bumps the x group with 2 updates in the / directory:
[golang.org/x/mod](https://github.com/golang/mod) and
[golang.org/x/tools](https://github.com/golang/tools).

Updates `golang.org/x/mod` from 0.23.0 to 0.24.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/mod/commit/dc121ce20ffab6bb810a0f231cfa9c24d3e51b29"><code>dc121ce</code></a>
all: upgrade go directive to at least 1.23.0 [generated]</li>
<li>See full diff in <a
href="https://github.com/golang/mod/compare/v0.23.0...v0.24.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/tools` from 0.30.0 to 0.31.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/tools/commit/6a5b66bef78dc7a1cf8593b276f35102ec0cb11c"><code>6a5b66b</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="https://github.com/golang/tools/commit/25a90befcdf96d15f13dd947b7395c8531dc67de"><code>25a90be</code></a>
gopls/internal/golang: Implementations for func types</li>
<li><a
href="https://github.com/golang/tools/commit/db6008cb90f09485deb11255e5dd6da114b4ecef"><code>db6008c</code></a>
go/types/internal/play: show Cursor.Stack of selected node</li>
<li><a
href="https://github.com/golang/tools/commit/ece9e9ba0760eb361376c8a890b24e89db031d9e"><code>ece9e9b</code></a>
gopls/doc/generate: add status in codelenses and inlayhints</li>
<li><a
href="https://github.com/golang/tools/commit/340f21a49b9cad20d07a2b58e483a991084dc481"><code>340f21a</code></a>
gopls: move gopls/doc/generate package</li>
<li><a
href="https://github.com/golang/tools/commit/07219402b2fc707689574d91ee3cfd2c9a544a87"><code>0721940</code></a>
gopls/internal/analysis/modernize: strings.Fields -&gt; FieldsSeq</li>
<li><a
href="https://github.com/golang/tools/commit/8d38122b0b1a9991f490aa06b7bfca7b4140bdad"><code>8d38122</code></a>
gopls/internal/cache: reproduce and fix crash on if cond overflow</li>
<li><a
href="https://github.com/golang/tools/commit/d81d6fcce1a24f2b8d0a9493f4d84b75c80176e4"><code>d81d6fc</code></a>
gopls/internal/util/asm: better assembly parsing</li>
<li><a
href="https://github.com/golang/tools/commit/455db21bd963fea3efdf0473e0ddce37313b8f91"><code>455db21</code></a>
gopls/internal/cache/parsego: fix OOB crash in fixInitStmt</li>
<li><a
href="https://github.com/golang/tools/commit/2b1f55036370bc9a05bed74aa13fa85fecce40e2"><code>2b1f550</code></a>
gopls/internal/analysis/gofix: allow literal array lengths</li>
<li>Additional commits viewable in <a
href="https://github.com/golang/tools/compare/v0.30.0...v0.31.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 07:32:04 +00:00
dependabot[bot] 61fdce85a9 chore: bump google.golang.org/api from 0.221.0 to 0.227.0 (#17073)
Bumps
[google.golang.org/api](https://github.com/googleapis/google-api-go-client)
from 0.221.0 to 0.227.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/releases">google.golang.org/api's
releases</a>.</em></p>
<blockquote>
<h2>v0.227.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.226.0...v0.227.0">0.227.0</a>
(2025-03-19)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3064">#3064</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/086437d5503dc5cc6794bbbfec47cdd90c8b917b">086437d</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3066">#3066</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/29203469556eca18b77dcf2f92163047218b5ad7">2920346</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3067">#3067</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c6396b197caa96a22a79dc8f993d8a216e7959db">c6396b1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3069">#3069</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/f12f50392dc68907c5616e8d436d7daafa2d9967">f12f503</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3070">#3070</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/a5a7982eab05780caeb754e4b489d3c1ff0d868c">a5a7982</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3071">#3071</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/a86ed9f6305ee23b7290ee047847ddcdf51c4792">a86ed9f</a>)</li>
</ul>
<h2>v0.226.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.225.0...v0.226.0">0.226.0</a>
(2025-03-13)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3059">#3059</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/36a4396b57da8f0b6f01fb1e4fd0b3a651469b35">36a4396</a>)</li>
</ul>
<h2>v0.225.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.224.0...v0.225.0">0.225.0</a>
(2025-03-11)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3052">#3052</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/6fe9ee700e1313bc01613809eb26089680de4f95">6fe9ee7</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3054">#3054</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1f9f6306edf6f040f94cb704c111e867de93b11c">1f9f630</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3055">#3055</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/01546c11d2c2bff28c3df26c055f5a37e2744c15">01546c1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3057">#3057</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/7a464eaf63831e1ee3f5d949ba19714560a15303">7a464ea</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3058">#3058</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1b9abf7810e1b19a8e69733377149a443865ec8f">1b9abf7</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>option:</strong> Update WithEndpoint docs (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3032">#3032</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/fe0dd61a4ed0f8708486f2aa417876bec8b6e5ae">fe0dd61</a>)</li>
</ul>
<h2>v0.224.0</h2>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.223.0...v0.224.0">0.224.0</a>
(2025-03-06)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3038">#3038</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/e50dbcf236706c31864e9dac2da4b8553ace321a">e50dbcf</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3040">#3040</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3acb9e0eb5ba64ab2d628cfb72ae9b6455123cba">3acb9e0</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3041">#3041</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3795b39b8e9788eaacb43d3a89681995a9571719">3795b39</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3042">#3042</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/7d1e8505fd427beceba3fa3a8fe82ecfa8c57d5c">7d1e850</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3043">#3043</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/eaeb698cbdc350788d93599f4454468dece92d00">eaeb698</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3048">#3048</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/0f2af0f23b3bb2fc6f0edb153b947a27e15be9be">0f2af0f</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md">google.golang.org/api's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.226.0...v0.227.0">0.227.0</a>
(2025-03-19)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3064">#3064</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/086437d5503dc5cc6794bbbfec47cdd90c8b917b">086437d</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3066">#3066</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/29203469556eca18b77dcf2f92163047218b5ad7">2920346</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3067">#3067</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/c6396b197caa96a22a79dc8f993d8a216e7959db">c6396b1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3069">#3069</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/f12f50392dc68907c5616e8d436d7daafa2d9967">f12f503</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3070">#3070</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/a5a7982eab05780caeb754e4b489d3c1ff0d868c">a5a7982</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3071">#3071</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/a86ed9f6305ee23b7290ee047847ddcdf51c4792">a86ed9f</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.225.0...v0.226.0">0.226.0</a>
(2025-03-13)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3059">#3059</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/36a4396b57da8f0b6f01fb1e4fd0b3a651469b35">36a4396</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.224.0...v0.225.0">0.225.0</a>
(2025-03-11)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3052">#3052</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/6fe9ee700e1313bc01613809eb26089680de4f95">6fe9ee7</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3054">#3054</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1f9f6306edf6f040f94cb704c111e867de93b11c">1f9f630</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3055">#3055</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/01546c11d2c2bff28c3df26c055f5a37e2744c15">01546c1</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3057">#3057</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/7a464eaf63831e1ee3f5d949ba19714560a15303">7a464ea</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3058">#3058</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/1b9abf7810e1b19a8e69733377149a443865ec8f">1b9abf7</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li><strong>option:</strong> Update WithEndpoint docs (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3032">#3032</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/fe0dd61a4ed0f8708486f2aa417876bec8b6e5ae">fe0dd61</a>)</li>
</ul>
<h2><a
href="https://github.com/googleapis/google-api-go-client/compare/v0.223.0...v0.224.0">0.224.0</a>
(2025-03-06)</h2>
<h3>Features</h3>
<ul>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3038">#3038</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/e50dbcf236706c31864e9dac2da4b8553ace321a">e50dbcf</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3040">#3040</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3acb9e0eb5ba64ab2d628cfb72ae9b6455123cba">3acb9e0</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3041">#3041</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/3795b39b8e9788eaacb43d3a89681995a9571719">3795b39</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3042">#3042</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/7d1e8505fd427beceba3fa3a8fe82ecfa8c57d5c">7d1e850</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3043">#3043</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/eaeb698cbdc350788d93599f4454468dece92d00">eaeb698</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3048">#3048</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/0f2af0f23b3bb2fc6f0edb153b947a27e15be9be">0f2af0f</a>)</li>
<li><strong>all:</strong> Auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3051">#3051</a>)
(<a
href="https://github.com/googleapis/google-api-go-client/commit/f10c130e16796c008f2e129322d5c8b366ecfc92">f10c130</a>)</li>
</ul>
<h3>Bug Fixes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/6c04eef38b09dc6bb68c69303b7fe5e761b1d523"><code>6c04eef</code></a>
chore(main): release 0.227.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3065">#3065</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/a86ed9f6305ee23b7290ee047847ddcdf51c4792"><code>a86ed9f</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3071">#3071</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/a5a7982eab05780caeb754e4b489d3c1ff0d868c"><code>a5a7982</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3070">#3070</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/4cd83927eccf1dac66ed73ac71b8a15e725cc112"><code>4cd8392</code></a>
chore(all): update all (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3068">#3068</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/f12f50392dc68907c5616e8d436d7daafa2d9967"><code>f12f503</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3069">#3069</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/c6396b197caa96a22a79dc8f993d8a216e7959db"><code>c6396b1</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3067">#3067</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/29203469556eca18b77dcf2f92163047218b5ad7"><code>2920346</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3066">#3066</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/086437d5503dc5cc6794bbbfec47cdd90c8b917b"><code>086437d</code></a>
feat(all): auto-regenerate discovery clients (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3064">#3064</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/be5fb5daa5e9ea3ed5d75a4c2ea98bc9871fe976"><code>be5fb5d</code></a>
chore(main): release 0.226.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3060">#3060</a>)</li>
<li><a
href="https://github.com/googleapis/google-api-go-client/commit/778942391f59823d37e2d7c3e08c07a5d51935a6"><code>7789423</code></a>
chore(deps): bump golang.org/x/net to 0.37.0 (<a
href="https://redirect.github.com/googleapis/google-api-go-client/issues/3063">#3063</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/googleapis/google-api-go-client/compare/v0.221.0...v0.227.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/api&package-manager=go_modules&previous-version=0.221.0&new-version=0.227.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 07:22:11 +00:00
dependabot[bot] c35fe22fe9 chore: bump github.com/chromedp/chromedp from 0.11.0 to 0.13.3 (#17072)
Bumps
[github.com/chromedp/chromedp](https://github.com/chromedp/chromedp)
from 0.11.0 to 0.13.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/chromedp/chromedp/releases">github.com/chromedp/chromedp's
releases</a>.</em></p>
<blockquote>
<h2>chromedp v0.13.2</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/chromedp/chromedp/compare/v0.13.1...v0.13.2">https://github.com/chromedp/chromedp/compare/v0.13.1...v0.13.2</a></p>
<h2>chromedp v0.13.0</h2>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/chromedp/chromedp/compare/v0.12.1...v0.13.0">https://github.com/chromedp/chromedp/compare/v0.12.1...v0.13.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/chromedp/chromedp/commit/f6fdfdd2948cd29f81304e9b8aebe3a5fbbd62d8"><code>f6fdfdd</code></a>
add tests for unmarshalling and marshalling json</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/6c2d3efb05830e6fe89ab8b570b25fb0fd302c4a"><code>6c2d3ef</code></a>
pass unmarshal and marshal options</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/eae0058f610a4cdadf1f4741c667e3b85f4ab635"><code>eae0058</code></a>
log syntactic errors when reading messages</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/9335dc30c27ce7e6cef9b024262074cf7a615ed2"><code>9335dc3</code></a>
Allow setting jsonv2 Marshal/Unmarshal options</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/71458e148d8c224238b015190347d02be51cb7b7"><code>71458e1</code></a>
fix: add page.EventFrameStartedNavigating to ignored events (Google
Chrome 13...</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/79abe0af356a869d2a4cbdb8a80f6a6d2017f522"><code>79abe0a</code></a>
Switching to jsonv2</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/229c63ebdce29abda43bc46a041b9aa14ba28baf"><code>229c63e</code></a>
Updating test workflow</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/a19bb90680a9a57df5dfc4f7e81af78568bef2e7"><code>a19bb90</code></a>
Updating LICENSE</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/6be1bcb299efa5c71570b6258076b896c3fc6690"><code>6be1bcb</code></a>
Updating device emulation</li>
<li><a
href="https://github.com/chromedp/chromedp/commit/f623c2d9f563c8f6512a25dd083d915938179d24"><code>f623c2d</code></a>
Updating dependencies</li>
<li>Additional commits viewable in <a
href="https://github.com/chromedp/chromedp/compare/v0.11.0...v0.13.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/chromedp/chromedp&package-manager=go_modules&previous-version=0.11.0&new-version=0.13.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 07:21:43 +00:00
dependabot[bot] 91b7664f9e chore: bump github.com/coreos/go-oidc/v3 from 3.12.0 to 3.13.0 (#16964)
Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc)
from 3.12.0 to 3.13.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/coreos/go-oidc/releases">github.com/coreos/go-oidc/v3's
releases</a>.</em></p>
<blockquote>
<h2>v3.13.0</h2>
<h2>What's Changed</h2>
<ul>
<li>*: bump dependency versions by <a
href="https://github.com/ericchiang"><code>@​ericchiang</code></a> in <a
href="https://redirect.github.com/coreos/go-oidc/pull/453">coreos/go-oidc#453</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/coreos/go-oidc/compare/v3.12.0...v3.13.0">https://github.com/coreos/go-oidc/compare/v3.12.0...v3.13.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/coreos/go-oidc/commit/60d436e8ea63774802ad6a0955f0c386edfefa8b"><code>60d436e</code></a>
*: bump dependency versions</li>
<li>See full diff in <a
href="https://github.com/coreos/go-oidc/compare/v3.12.0...v3.13.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/coreos/go-oidc/v3&package-manager=go_modules&previous-version=3.12.0&new-version=3.13.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 07:21:36 +00:00
dependabot[bot] 13f1a3f259 chore: bump github.com/spf13/afero from 1.12.0 to 1.14.0 (#16961)
Bumps [github.com/spf13/afero](https://github.com/spf13/afero) from
1.12.0 to 1.14.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/spf13/afero/releases">github.com/spf13/afero's
releases</a>.</em></p>
<blockquote>
<h2>v1.14.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Split gcsfs and sftpfs into separate modules by <a
href="https://github.com/sagikazarmark"><code>@​sagikazarmark</code></a>
in <a
href="https://redirect.github.com/spf13/afero/pull/462">spf13/afero#462</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/spf13/afero/compare/v1.13.0...v1.14.0">https://github.com/spf13/afero/compare/v1.13.0...v1.14.0</a></p>
<h2>v1.13.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump actions/setup-go from 5.2.0 to 5.3.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/446">spf13/afero#446</a></li>
<li>Bump golangci/golangci-lint-action from 6.1.1 to 6.3.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/451">spf13/afero#451</a></li>
<li>Bump golang.org/x/text from 0.21.0 to 0.22.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/452">spf13/afero#452</a></li>
<li>Bump golang.org/x/oauth2 from 0.25.0 to 0.26.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/453">spf13/afero#453</a></li>
<li>Bump golangci/golangci-lint-action from 6.3.0 to 6.3.3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/459">spf13/afero#459</a></li>
<li>Bump golang.org/x/crypto from 0.32.0 to 0.33.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/455">spf13/afero#455</a></li>
<li>Bump golangci/golangci-lint-action from 6.3.3 to 6.5.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/460">spf13/afero#460</a></li>
<li>ci: add Go 1.24 to the test matrix by <a
href="https://github.com/sagikazarmark"><code>@​sagikazarmark</code></a>
in <a
href="https://redirect.github.com/spf13/afero/pull/461">spf13/afero#461</a></li>
<li>Bump golangci/golangci-lint-action from 6.5.0 to 6.5.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/spf13/afero/pull/473">spf13/afero#473</a></li>
<li>Update dependencies by <a
href="https://github.com/sagikazarmark"><code>@​sagikazarmark</code></a>
in <a
href="https://redirect.github.com/spf13/afero/pull/477">spf13/afero#477</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/dependabot"><code>@​dependabot</code></a> made
their first contribution in <a
href="https://redirect.github.com/spf13/afero/pull/446">spf13/afero#446</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/spf13/afero/compare/v1.12.0...v1.13.0">https://github.com/spf13/afero/compare/v1.12.0...v1.13.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/spf13/afero/commit/ea38482beffb2485aed022e0c1ed3b4b561f67b6"><code>ea38482</code></a>
Merge pull request <a
href="https://redirect.github.com/spf13/afero/issues/462">#462</a> from
spf13/dependencies</li>
<li><a
href="https://github.com/spf13/afero/commit/a9aaabc51a41042d41595255ba13d62fdefd4561"><code>a9aaabc</code></a>
docs: add release instructions</li>
<li><a
href="https://github.com/spf13/afero/commit/d3a70b6f8258ab362e5190c01c21ade617fad9ec"><code>d3a70b6</code></a>
ci: run tests for submodules</li>
<li><a
href="https://github.com/spf13/afero/commit/2af192559d89b03611b3ce4c70f9a72ec01f0439"><code>2af1925</code></a>
feat: split gcsfs and sftpfs into separate modules</li>
<li><a
href="https://github.com/spf13/afero/commit/dbd6f6174e148a5b54b151b4cfc31dc8a4423451"><code>dbd6f61</code></a>
Merge pull request <a
href="https://redirect.github.com/spf13/afero/issues/477">#477</a> from
spf13/update-dependencies</li>
<li><a
href="https://github.com/spf13/afero/commit/83b8a558532728814aafd233cbfd9e9642abe7af"><code>83b8a55</code></a>
update readme</li>
<li><a
href="https://github.com/spf13/afero/commit/bf3bd7346b551cccadf936d821b982799daa6843"><code>bf3bd73</code></a>
update dependencies</li>
<li><a
href="https://github.com/spf13/afero/commit/464bc9859a5863a4c49e18b973b1398c0ac465f3"><code>464bc98</code></a>
Merge pull request <a
href="https://redirect.github.com/spf13/afero/issues/473">#473</a> from
spf13/dependabot/github_actions/golangci/golangc...</li>
<li><a
href="https://github.com/spf13/afero/commit/da239a4ded2831f87f4df336563d3d4b8bd1abaf"><code>da239a4</code></a>
Bump golangci/golangci-lint-action from 6.5.0 to 6.5.1</li>
<li><a
href="https://github.com/spf13/afero/commit/523f621845f8f2bd5aebb28650957b06b8778598"><code>523f621</code></a>
Merge pull request <a
href="https://redirect.github.com/spf13/afero/issues/461">#461</a> from
spf13/go124</li>
<li>Additional commits viewable in <a
href="https://github.com/spf13/afero/compare/v1.12.0...v1.14.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/spf13/afero&package-manager=go_modules&previous-version=1.12.0&new-version=1.14.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 07:21:21 +00:00
dependabot[bot] 64b434b47b chore: bump github.com/charmbracelet/glamour from 0.8.0 to 0.9.1 (#17071)
Bumps
[github.com/charmbracelet/glamour](https://github.com/charmbracelet/glamour)
from 0.8.0 to 0.9.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/charmbracelet/glamour/releases">github.com/charmbracelet/glamour's
releases</a>.</em></p>
<blockquote>
<h2>v0.9.1</h2>
<p>Some users were reporting occasional checksum miss matches when
building using Glamour v0.9.0.
This release provides a new tag to hopefully fix this.</p>
<h2>Changelog</h2>
<h3>Other work</h3>
<ul>
<li>dddb9a72f081205b9e18a34d093c673230e96f8b: ci: sync golangci-lint
config (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/403">#403</a>)
(<a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot])</li>
</ul>
<hr />
<p><!-- raw HTML omitted --><!-- raw HTML omitted --><!-- raw HTML
omitted --></p>
<p>Thoughts? Questions? We love hearing from you. Feel free to reach out
on <a href="https://twitter.com/charmcli">Twitter</a>, <a
href="https://mastodon.technology/@charm">The Fediverse</a>, or on <a
href="https://charm.sh/chat">Discord</a>.</p>
<h2>v0.9.0</h2>
<h1>Better Syntax Highlighting, Better Tables</h1>
<p>It's totally time for a Glamour release right? This release features
a nice lil' contribution from the <a
href="https://github.com/github"><code>@​github</code></a> CLI team and
pulls in some big table improvements from Lip Gloss upstream. Let's
go!</p>
<h2>Specifying Chroma Styles</h2>
<p>Thanks to valiant efforts of <a
href="https://github.com/andyfeller"><code>@​andyfeller</code></a> and
<a
href="https://github.com/williammartin"><code>@​williammartin</code></a>
at <a href="https://github.com/github"><code>@​github</code></a>, you
can now use <a
href="https://pkg.go.dev/github.com/charmbracelet/glamour@v0.9.0#WithChromaFormatter"><code>glamour.WithChromaFormatter</code></a>
to specify an exact <a
href="https://github.com/alecthomas/chroma">Chroma</a> style to use,
independent of the higher level style.</p>
<pre lang="go"><code>myHotOps := glamour.WithOptions(
    glamour.WithChromaFormatter(&quot;terminal16&quot;),
    glamour.WithStandardStyle(&quot;dark&quot;),
)
</code></pre>
<p>As a bonus, you can also use <a
href="https://pkg.go.dev/github.com/charmbracelet/glamour@v0.9.0#WithOptions"><code>glamour.WithOptions</code></a>
as a meta layer for grouping options.</p>
<h2>Better Tables</h2>
<p>This release also reaps the benefits from the table rendering
overhaul in <a
href="https://github.com/charmbracelet/lipgloss/releases/tag/v1.1.0">Lip
Gloss v1.1.0</a>! Glamour will now be much smarter when it comes to
deciding column widths, and the content will not wrap appropriately
instead of just being cut when it won't fit.</p>
<h2>Changelog</h2>
<h3>New Features</h3>
<ul>
<li>4c040b7fd5c023154de93d5c0f789111ea06c82c: feat: add term renderer
option for chroma formatter (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/395">#395</a>)
(<a
href="https://github.com/williammartin"><code>@​williammartin</code></a>)</li>
<li>39de44871fad9d547af5975ae220f2034642304a: feat(ci): use goreleaser
(<a
href="https://redirect.github.com/charmbracelet/glamour/issues/348">#348</a>)
(<a
href="https://github.com/aymanbagabas"><code>@​aymanbagabas</code></a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>f43b1ad9ef09b10a93837e07ae2c18b66bceac5c: fix(tables): pin lipgloss
to v1.1.0 for table improvements; update tests (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/394">#394</a>)
(<a
href="https://github.com/andreynering"><code>@​andreynering</code></a>)</li>
<li>bdc4ec5217e146f5a57be8a3e0a14a3ddee3f749: fix(table): fix rendering
table in ascii-only mode (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/393">#393</a>)
(<a
href="https://github.com/andreynering"><code>@​andreynering</code></a>)</li>
<li>9cedacac492db45121a984505f3f4d87277dcde3: fix: render right margin
for block stack elements (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/334">#334</a>)
(<a href="https://github.com/jahvon"><code>@​jahvon</code></a>)</li>
</ul>
<h3>Documentation updates</h3>
<ul>
<li>f29dc10685689be9846671030e07a17f97bafb16: docs(example): update
example to demonstrate color downsampling (<a
href="https://github.com/meowgorithm"><code>@​meowgorithm</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/charmbracelet/glamour/commit/dddb9a72f081205b9e18a34d093c673230e96f8b"><code>dddb9a7</code></a>
ci: sync golangci-lint config (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/403">#403</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/f43b1ad9ef09b10a93837e07ae2c18b66bceac5c"><code>f43b1ad</code></a>
test(tables): pin lipgloss to v1.1.0 and update tests (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/394">#394</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/d1d5125cfab42203495f15b846e901d0c1f37aaa"><code>d1d5125</code></a>
chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 in /examples
(<a
href="https://redirect.github.com/charmbracelet/glamour/issues/400">#400</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/3b686ba19d5fdb7762e82f1d10348aec65e149c8"><code>3b686ba</code></a>
chore(deps): bump golang.org/x/net from 0.33.0 to 0.36.0 (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/399">#399</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/4c040b7fd5c023154de93d5c0f789111ea06c82c"><code>4c040b7</code></a>
feat: add term renderer option for chroma formatter (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/395">#395</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/3dc6c5b8d878b1164940c0d5ac97f3943717d71d"><code>3dc6c5b</code></a>
chore(deps): bump golang.org/x/text from 0.22.0 to 0.23.0 (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/397">#397</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/5ad6fac7cea48dc390efa654b30edcd05ff81c0a"><code>5ad6fac</code></a>
chore(deps): bump golang.org/x/term from 0.29.0 to 0.30.0 (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/396">#396</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/bdc4ec5217e146f5a57be8a3e0a14a3ddee3f749"><code>bdc4ec5</code></a>
fix(table): fix rendering table in ascii-only mode (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/393">#393</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/b0776ab61085cc90418f9a902ae5c80994d567e3"><code>b0776ab</code></a>
chore(deps): bump github.com/yuin/goldmark-emoji from 1.0.4 to 1.0.5 (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/391">#391</a>)</li>
<li><a
href="https://github.com/charmbracelet/glamour/commit/ddc245101b5967e287cbc8f09a163bdc4e7404b5"><code>ddc2451</code></a>
chore(deps): bump golang.org/x/text from 0.21.0 to 0.22.0 (<a
href="https://redirect.github.com/charmbracelet/glamour/issues/392">#392</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/charmbracelet/glamour/compare/v0.8.0...v0.9.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/charmbracelet/glamour&package-manager=go_modules&previous-version=0.8.0&new-version=0.9.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 07:09:53 +00:00
dependabot[bot] 38f404fcaf chore: bump vite from 5.4.14 to 5.4.15 in /site (#17101)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite)
from 5.4.14 to 5.4.15.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/releases">vite's
releases</a>.</em></p>
<blockquote>
<h2>v5.4.15</h2>
<p>Please refer to <a
href="https://github.com/vitejs/vite/blob/v5.4.15/packages/vite/CHANGELOG.md">CHANGELOG.md</a>
for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/vitejs/vite/blob/v5.4.15/packages/vite/CHANGELOG.md">vite's
changelog</a>.</em></p>
<blockquote>
<h2><!-- raw HTML omitted -->5.4.15 (2025-03-24)<!-- raw HTML omitted
--></h2>
<ul>
<li>fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19702">#19702</a>,
fs raw query with query separators (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19703">#19703</a>)
(<a
href="https://github.com/vitejs/vite/commit/807d7f06d33ab49c48a2a3501da3eea1906c0d41">807d7f0</a>),
closes <a
href="https://redirect.github.com/vitejs/vite/issues/19702">#19702</a>
<a
href="https://redirect.github.com/vitejs/vite/issues/19703">#19703</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vitejs/vite/commit/9b0f4c80eea8b136d262c705234353e96abfbe75"><code>9b0f4c8</code></a>
release: v5.4.15</li>
<li><a
href="https://github.com/vitejs/vite/commit/807d7f06d33ab49c48a2a3501da3eea1906c0d41"><code>807d7f0</code></a>
fix: backport <a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19702">#19702</a>,
fs raw query with query separators (<a
href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/19703">#19703</a>)</li>
<li>See full diff in <a
href="https://github.com/vitejs/vite/commits/v5.4.15/packages/vite">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vite&package-manager=npm_and_yarn&previous-version=5.4.14&new-version=5.4.15)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 07:08:05 +00:00
Jon Ayers 17ddee05e5 chore: update golang to 1.24.1 (#17035)
- Update go.mod to use Go 1.24.1
- Update GitHub Actions setup-go action to use Go 1.24.1
- Fix linting issues with golangci-lint by:
  - Updating to golangci-lint v1.57.1 (more compatible with Go 1.24.1)

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
2025-03-26 01:56:39 -05:00
Danielle Maywood c131d01cfd chore: disallow inbox as default method (#17093)
Disallow setting `inbox` as the default notifications method.
2025-03-25 20:10:15 +00:00
brettkolodny cf10d98aab fix: improve error message when deleting organization with resources (#17049)
Closes
[coder/internal#477](https://github.com/coder/internal/issues/477)

![Screenshot 2025-03-21 at 11 25
57 AM](https://github.com/user-attachments/assets/50cc03e9-395d-4fc7-8882-18cb66b1fac9)

I'm solving this issue in two parts:

1. Updated the postgres function so that it doesn't omit 0 values in the
error
2. Created a new query to fetch the number of resources associated with
an organization and using that information to provider a cleaner error
message to the frontend

> **_NOTE:_** SQL is not my strong suit, and the code was created with
the help of AI. So I'd take extra time looking over what I wrote there
2025-03-25 15:31:24 -04:00
Bruno Quaresma 2c53f7ae7c feat: mark notification as read when action is clicked (#17095)
When a user clicks in a notification action we can infer the
notification was read.
2025-03-25 14:29:52 -03:00
Bruno Quaresma 33029c39c0 fix: fix load more notifications only working once (#17094)
The "load more" button in the notifications inbox were only working
once. After taking a look at the code the issue was found and fixed.
2025-03-25 13:43:01 -03:00
Mathias Fredriksson 5c8cac9fb7 feat: add name to workspace agent devcontainers (#17089)
In the presence of multiple devcontainers, it would be nice to
differentiate them by name. This change inherits the resource name from
terraform.

Refs #17076
2025-03-25 12:59:20 +00:00
Marcin Tojek 56082f3b83 feat(cli): start workspace in no-wait mode (#17087)
Fixes: https://github.com/coder/coder/issues/16408
2025-03-25 13:54:53 +01:00
Danielle Maywood cd19e79d9b chore: enable coder inbox by default (#17077)
Add a flag to enable Coder Inbox by default, as well as supporting disabling the feature.
2025-03-25 12:51:26 +00:00
Spike Curtis 5f3a53f01b fix: fix race condition in pubsub startup (#17088)
fixes https://github.com/coder/internal/issues/525

If the context is canceled, the goroutine that is supposed to read from the `errCh` could exit prematurely, leading to a goroutine leak. Refactors this code so it cannot block.
2025-03-25 16:45:45 +04:00
Danny Kopping 4c33846f6d chore: add prebuilds system user (#16916)
Pre-requisite for https://github.com/coder/coder/pull/16891

Closes https://github.com/coder/internal/issues/515

This PR introduces a new concept of a "system" user.

Our data model requires that all workspaces have an owner (a `users`
relation), and prebuilds is a feature that will spin up workspaces to be
claimed later by actual users - and thus needs to own the workspaces in
the interim.

Naturally, introducing a change like this touches a few aspects around
the codebase and we've taken the approach _default hidden_ here; in
other words, queries for users will by default _exclude_ all system
users, but there is a flag to ensure they can be displayed. This keeps
the changeset relatively small.

This user has minimal permissions (it's equivalent to a `member` since
it has no roles). It will be associated with the default org in the
initial migration, and thereafter we'll need to somehow ensure its
membership aligns with templates (which are org-scoped) for which it'll
need to provision prebuilds; that's a solution we'll have in a
subsequent PR.

---------

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
Co-authored-by: Sas Swart <sas.swart.cdk@gmail.com>
2025-03-25 12:18:06 +00:00
Spike Curtis 117e4c2fe7 feat: adds device_id, device_os, and coder_desktop_version to telemetry (#17086)
Records the Device ID, Device OS and Coder Desktop version to telemetry.

These values are provided by the Coder Desktop client in the StartRequest method of the VPN protocol. We render them as an HTTP header to transmit to Coderd, where they are decoded and added to telemetry.
2025-03-25 15:26:05 +04:00
Hugo Dutka d5557fcbf5 fix: implement device auth rate limit handling (#17079)
The [OAuth2
specification](https://datatracker.ietf.org/doc/html/rfc8628) describes
how clients in the device flow should handle retrying requests when they
are rate limited.

We didn't respect it, which sometimes prevented users from logging in or
setting up external auth. They'd see a `slow_down` error in the UI and
would be unable to complete the authentication flow. This PR implements
rate limit handling according to the spec.
2025-03-25 11:32:03 +01:00
Vincent Vielle 7b65422ef3 fix: change notifications actions url (#17083)
Related to #17082

Some notifications ( workspace created and workspace manually updated )
are using wrong variables to build the Action URL. Fixing it.
2025-03-25 11:29:02 +01:00
Marcin Tojek 081679f431 fix: display force-tty flag (#17067)
Fixes: https://github.com/coder/coder/issues/17033
2025-03-25 10:25:35 +01:00
Jon Ayers 8da568b132 chore: update Terraform version from 1.11.0 to 1.11.2 (#17081)
🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <claude@anthropic.com>
2025-03-25 00:57:15 -05:00
Edward Angert 4983150ab9 docs: add a table to feature stages doc (#17080)
adds a table to the feature stages doc to summarize the stages + links
to the heading below for more info


[preview](https://coder.com/docs/@feature-stages-table/about/feature-stages)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-24 22:28:02 -04:00
M Atif Ali 51cfec3261 chore: reuse syft and cosign install actions across workflows (#16981)
This pull request adds new GitHub Actions for installing `cosign` and
`syft`, and updates the CI, release, and security workflows.

**New Actions:**  
- [`install-cosign`](.github/actions/install-cosign/action.yaml):
Installs `cosign` with a configurable version.
- [`install-syft`](.github/actions/install-syft/action.yaml): Installs
`syft` with a configurable version.

**Workflow Updates:**  
- CI, release, and security workflows now use `install-cosign` and
`install-syft`.
2025-03-25 01:22:17 +00:00
Bruno Quaresma e8d5f98ede feat: support markdown in notifications (#17075)
To make the notification content more appealing, we are sending the
notification content as markdown from the server, so we need to adjust
the FE to display it properly.
2025-03-24 13:46:43 -03:00
ケイラ 5b3eda6719 chore: persist template import terraform plan in postgres (#17012) 2025-03-24 10:01:50 -06:00
Cian Johnston 445a059da2 ci: standardize on go 1.22.12 (#17047)
Standardizes on go1.22.12 in go.mod and in dogfood Dockerfile
2025-03-24 16:00:07 +00:00
Mathias Fredriksson d570ce7246 test(provisioner/terraform): clean up testdata structure (#17074) 2025-03-24 16:34:56 +02:00
dependabot[bot] 4e38e6de04 ci: bump the github-actions group with 8 updates (#17068)
Bumps the github-actions group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/cache](https://github.com/actions/cache) | `4.2.2` | `4.2.3`
|
| [actions/upload-artifact](https://github.com/actions/upload-artifact)
| `4.6.1` | `4.6.2` |
|
[actions/download-artifact](https://github.com/actions/download-artifact)
| `4.1.9` | `4.2.1` |
|
[tj-actions/changed-files](https://github.com/tj-actions/changed-files)
| `531f5f7d163941f0c1c04e0ff4d8bb243ac4366f` |
`27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99` |
| [tj-actions/branch-names](https://github.com/tj-actions/branch-names)
| `8.0.1` | `8.1.0` |
| [github/codeql-action](https://github.com/github/codeql-action) |
`3.28.11` | `3.28.12` |
|
[beatlabs/delete-old-branches-action](https://github.com/beatlabs/delete-old-branches-action)
| `0.0.10` | `0.0.11` |
|
[umbrelladocs/action-linkspector](https://github.com/umbrelladocs/action-linkspector)
| `1.2.5` | `1.3.2` |

Updates `actions/cache` from 4.2.2 to 4.2.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/releases">actions/cache's
releases</a>.</em></p>
<blockquote>
<h2>v4.2.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Update to use <code>@​actions/cache</code> 4.0.3 package &amp;
prepare for new release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1577">actions/cache#1577</a>
(SAS tokens for cache entries are now masked in debug logs)</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/cache/pull/1577">actions/cache#1577</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v4.2.2...v4.2.3">https://github.com/actions/cache/compare/v4.2.2...v4.2.3</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/blob/main/RELEASES.md">actions/cache's
changelog</a>.</em></p>
<blockquote>
<h1>Releases</h1>
<h3>4.2.3</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v4.0.3 (obfuscates SAS token in
debug logs for cache entries)</li>
</ul>
<h3>4.2.2</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v4.0.2</li>
</ul>
<h3>4.2.1</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v4.0.1</li>
</ul>
<h3>4.2.0</h3>
<p>TLDR; The cache backend service has been rewritten from the ground up
for improved performance and reliability. <a
href="https://github.com/actions/cache">actions/cache</a> now integrates
with the new cache service (v2) APIs.</p>
<p>The new service will gradually roll out as of <strong>February 1st,
2025</strong>. The legacy service will also be sunset on the same date.
Changes in these release are <strong>fully backward
compatible</strong>.</p>
<p><strong>We are deprecating some versions of this action</strong>. We
recommend upgrading to version <code>v4</code> or <code>v3</code> as
soon as possible before <strong>February 1st, 2025.</strong> (Upgrade
instructions below).</p>
<p>If you are using pinned SHAs, please use the SHAs of versions
<code>v4.2.0</code> or <code>v3.4.0</code></p>
<p>If you do not upgrade, all workflow runs using any of the deprecated
<a href="https://github.com/actions/cache">actions/cache</a> will
fail.</p>
<p>Upgrading to the recommended versions will not break your
workflows.</p>
<h3>4.1.2</h3>
<ul>
<li>Add GitHub Enterprise Cloud instances hostname filters to inform API
endpoint choices - <a
href="https://redirect.github.com/actions/cache/pull/1474">#1474</a></li>
<li>Security fix: Bump braces from 3.0.2 to 3.0.3 - <a
href="https://redirect.github.com/actions/cache/pull/1475">#1475</a></li>
</ul>
<h3>4.1.1</h3>
<ul>
<li>Restore original behavior of <code>cache-hit</code> output - <a
href="https://redirect.github.com/actions/cache/pull/1467">#1467</a></li>
</ul>
<h3>4.1.0</h3>
<ul>
<li>Ensure <code>cache-hit</code> output is set when a cache is missed -
<a
href="https://redirect.github.com/actions/cache/pull/1404">#1404</a></li>
<li>Deprecate <code>save-always</code> input - <a
href="https://redirect.github.com/actions/cache/pull/1452">#1452</a></li>
</ul>
<h3>4.0.2</h3>
<ul>
<li>Fixed restore <code>fail-on-cache-miss</code> not working.</li>
</ul>
<h3>4.0.1</h3>
<ul>
<li>Updated <code>isGhes</code> check</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/cache/commit/5a3ec84eff668545956fd18022155c47e93e2684"><code>5a3ec84</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1577">#1577</a>
from salmanmkc/salmanmkc/4-test</li>
<li><a
href="https://github.com/actions/cache/commit/7de21022a7b6824c106a9847befcbd8154b45b6a"><code>7de2102</code></a>
Update releases.md</li>
<li><a
href="https://github.com/actions/cache/commit/76d40dd347779762a1c829bbeeda5da4d81ca8c1"><code>76d40dd</code></a>
Update to use the latest version of the cache package to obfuscate the
SAS</li>
<li><a
href="https://github.com/actions/cache/commit/76dd5eb692f606c28d4b7a4ea7cfdffc926ba06a"><code>76dd5eb</code></a>
update cache with main</li>
<li><a
href="https://github.com/actions/cache/commit/8c80c27c5e4498d5675b05fb1eff96a56c593b06"><code>8c80c27</code></a>
new package</li>
<li><a
href="https://github.com/actions/cache/commit/45cfd0e7fffd1869ea4d5bfb54a464d825c1f742"><code>45cfd0e</code></a>
updates</li>
<li><a
href="https://github.com/actions/cache/commit/edd449b9cf39c2a20dc7c3d505ff6dc193c48a02"><code>edd449b</code></a>
updated cache with latest changes</li>
<li><a
href="https://github.com/actions/cache/commit/0576707e373f92196b81695442ed3f80c347f9c7"><code>0576707</code></a>
latest test before pr</li>
<li><a
href="https://github.com/actions/cache/commit/3105dc9754dd9cd935ffcf45c091ed2cadbf42b9"><code>3105dc9</code></a>
update</li>
<li><a
href="https://github.com/actions/cache/commit/9450d42d15022999ad2fa60a8b91f01fc92a0563"><code>9450d42</code></a>
mask</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/cache/compare/d4323d4df104b026a6aa633fdb11d772146be0bf...5a3ec84eff668545956fd18022155c47e93e2684">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/upload-artifact` from 4.6.1 to 4.6.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v4.6.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Update to use artifact 2.3.2 package &amp; prepare for new
upload-artifact release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/685">actions/upload-artifact#685</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/685">actions/upload-artifact#685</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v4...v4.6.2">https://github.com/actions/upload-artifact/compare/v4...v4.6.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/upload-artifact/commit/ea165f8d65b6e75b540449e92b4886f43607fa02"><code>ea165f8</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/685">#685</a>
from salmanmkc/salmanmkc/3-new-upload-artifacts-release</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/08396203c179e13c71b9754ce3472ed71842eec0"><code>0839620</code></a>
Prepare for new release of actions/upload-artifact with new toolkit
cache ver...</li>
<li>See full diff in <a
href="https://github.com/actions/upload-artifact/compare/4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1...ea165f8d65b6e75b540449e92b4886f43607fa02">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/download-artifact` from 4.1.9 to 4.2.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v4.2.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Add unit tests by <a
href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/392">actions/download-artifact#392</a></li>
<li>Fix bug introduced in 4.2.0 by <a
href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/391">actions/download-artifact#391</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v4.2.0...v4.2.1">https://github.com/actions/download-artifact/compare/v4.2.0...v4.2.1</a></p>
<h2>v4.2.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README.md by <a
href="https://github.com/lkfortuna"><code>@​lkfortuna</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/384">actions/download-artifact#384</a></li>
<li>Bump artifact version, do digest check by <a
href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/383">actions/download-artifact#383</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/lkfortuna"><code>@​lkfortuna</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/384">actions/download-artifact#384</a></li>
<li><a href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/383">actions/download-artifact#383</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v4.1.9...v4.2.0">https://github.com/actions/download-artifact/compare/v4.1.9...v4.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/download-artifact/commit/95815c38cf2ff2164869cbab79da8d1f422bc89e"><code>95815c3</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/391">#391</a>
from GhadimiR/main</li>
<li><a
href="https://github.com/actions/download-artifact/commit/278fca438a0f334c0505181835b4796f2785949b"><code>278fca4</code></a>
Move log statements</li>
<li><a
href="https://github.com/actions/download-artifact/commit/68909842a1073010f1cf920ed7f153e2948f9c16"><code>6890984</code></a>
Merge branch 'main' into main</li>
<li><a
href="https://github.com/actions/download-artifact/commit/f9415c0ec30f02c18e075f091cafcfe4159168d0"><code>f9415c0</code></a>
Run unit tests in CI</li>
<li><a
href="https://github.com/actions/download-artifact/commit/76a6eb5cbca98dccb5e14c0116e53f5df13b220d"><code>76a6eb5</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/392">#392</a>
from GhadimiR/add_unit_tests</li>
<li><a
href="https://github.com/actions/download-artifact/commit/a2426d7c4522072f4d5824c9508d7ea97107cb8e"><code>a2426d7</code></a>
Merge branch 'main' into add_unit_tests</li>
<li><a
href="https://github.com/actions/download-artifact/commit/3ffa694f6f7e3d53f63807f78267796f57911dd4"><code>3ffa694</code></a>
lint</li>
<li><a
href="https://github.com/actions/download-artifact/commit/53f6aa5f93b626e252398abac720a28f6eb048ed"><code>53f6aa5</code></a>
Add extra assertion to download single artifact test</li>
<li><a
href="https://github.com/actions/download-artifact/commit/b456700053c87aa7d6b31d212292755e1e6eb923"><code>b456700</code></a>
lint</li>
<li><a
href="https://github.com/actions/download-artifact/commit/9eab798a9885c1be58a1c4381da1109644016e98"><code>9eab798</code></a>
Configure tsconfig</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/download-artifact/compare/cc203385981b70ca67e1cc392babf9cc229d5806...95815c38cf2ff2164869cbab79da8d1f422bc89e">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/changed-files` from
531f5f7d163941f0c1c04e0ff4d8bb243ac4366f to
27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/changed-files/blob/main/HISTORY.md">tj-actions/changed-files's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.2...v46.0.3">46.0.3</a>
- (2025-03-23)</h1>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2501">#2501</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/41e0de576a0f2b64d9f06f2773f539109e55a70a">41e0de5</a>)
- (github-actions[bot])</p>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2499">#2499</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/945787811a795cd840a1157ac590dd7827a05c8e">9457878</a>)
- (github-actions[bot])</p>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<ul>
<li>Remove warning (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2504">#2504</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/813235684248c47a3518575ef56906084b59e7e8">8132356</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li><strong>deps:</strong> Bump test/demo from <code>5dfac2e</code> to
<code>c6bd3b3</code> (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2505">#2505</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/823fcebdb31bb35fdf2229d9f769b400309430d0">823fceb</a>)
- (dependabot[bot])</li>
<li>Pin github actions (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2503">#2503</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/7a369a71758acce79205e5145cb728a08ae607fb">7a369a7</a>)
- (Tonye Jack)</li>
<li><strong>deps-dev:</strong> Bump <code>@​types/node</code> from
22.13.10 to 22.13.11 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2502">#2502</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/9468856c2214566e4f7d96d3a018fb3e889a4d6d">9468856</a>)
- (dependabot[bot])</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded to v46.0.2 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2500">#2500</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted -->
Co-authored-by: Tonye Jack <a
href="mailto:jtonye@ymail.com">jtonye@ymail.com</a> (<a
href="https://github.com/tj-actions/changed-files/commit/401c7227d10aad0ed26ab13735f1b290c3bcc919">401c722</a>)
- (github-actions[bot])</p>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.1...v46.0.2">46.0.2</a>
- (2025-03-22)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li>Update log message when attempting to locate merge base (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2493">#2493</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/a5cad85977a53287a694f9509c03feb50ac58428">a5cad85</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted --> Add</h2>
<ul>
<li>Add hint to revoke leaked token (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2475">#2475</a>)</li>
</ul>
<p>(<a
href="https://github.com/tj-actions/changed-files/commit/d52b942ee0c535798f0df9e1c05683f8e818c79b">d52b942</a>)
- (undefined)</p>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2496">#2496</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/9cc867cd4a5df418b1538ffecaaef26144a0e51f">9cc867c</a>)
- (github-actions[bot])</p>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2492">#2492</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/f2f439bb2f890f0ec22e3ca95985b46003688a8f">f2f439b</a>)
- (github-actions[bot])</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/changed-files/commit/27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99"><code>27ae6b3</code></a>
Upgraded to v46.0.3 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2506">#2506</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/823fcebdb31bb35fdf2229d9f769b400309430d0"><code>823fceb</code></a>
chore(deps): bump test/demo from <code>5dfac2e</code> to
<code>c6bd3b3</code> (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2505">#2505</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/813235684248c47a3518575ef56906084b59e7e8"><code>8132356</code></a>
doc: remove warning (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2504">#2504</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/7a369a71758acce79205e5145cb728a08ae607fb"><code>7a369a7</code></a>
chore: pin github actions (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2503">#2503</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/9468856c2214566e4f7d96d3a018fb3e889a4d6d"><code>9468856</code></a>
chore(deps-dev): bump <code>@​types/node</code> from 22.13.10 to
22.13.11 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2502">#2502</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/401c7227d10aad0ed26ab13735f1b290c3bcc919"><code>401c722</code></a>
Upgraded to v46.0.2 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2500">#2500</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/41e0de576a0f2b64d9f06f2773f539109e55a70a"><code>41e0de5</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2501">#2501</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/945787811a795cd840a1157ac590dd7827a05c8e"><code>9457878</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2499">#2499</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/26a38635fc1173cc5820336ce97be6188d0de9f5"><code>26a3863</code></a>
docs: add undefined-moe as a contributor for doc (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2498">#2498</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/a530a27a793d93d428bac022c621a9ed52f75efd"><code>a530a27</code></a>
chore: update sync-release-version.yml to use commit hash for tags in
docs (#...</li>
<li>Additional commits viewable in <a
href="https://github.com/tj-actions/changed-files/compare/531f5f7d163941f0c1c04e0ff4d8bb243ac4366f...27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/branch-names` from 8.0.1 to 8.1.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/branch-names/releases">tj-actions/branch-names's
releases</a>.</em></p>
<blockquote>
<h2>v8.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Upgraded to v8.0.2 by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/407">tj-actions/branch-names#407</a></li>
<li>feat: add support for strip_branch_prefix by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/406">tj-actions/branch-names#406</a></li>
<li>Updated README.md by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/408">tj-actions/branch-names#408</a></li>
<li>chore: Update test.yml by <a
href="https://github.com/jackton1"><code>@​jackton1</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/409">tj-actions/branch-names#409</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/tj-actions/branch-names/compare/v8...v8.1.0">https://github.com/tj-actions/branch-names/compare/v8...v8.1.0</a></p>
<h2>v8.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Upgraded to v8.0.1 by <a
href="https://github.com/tj-actions-bot"><code>@​tj-actions-bot</code></a>
in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/283">tj-actions/branch-names#283</a></li>
<li>chore(deps): update codacy/codacy-analysis-cli-action action to
v4.4.0 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/284">tj-actions/branch-names#284</a></li>
<li>chore(deps): update tj-actions/verify-changed-files action to v19 by
<a href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/285">tj-actions/branch-names#285</a></li>
<li>docs: add boidolr as a contributor for doc by <a
href="https://github.com/allcontributors"><code>@​allcontributors</code></a>
in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/287">tj-actions/branch-names#287</a></li>
<li>Updated README.md by <a
href="https://github.com/tj-actions-bot"><code>@​tj-actions-bot</code></a>
in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/288">tj-actions/branch-names#288</a></li>
<li>docs: update checkout action by <a
href="https://github.com/boidolr"><code>@​boidolr</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/286">tj-actions/branch-names#286</a></li>
<li>chore(deps): update actions/checkout action to v4.1.2 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/290">tj-actions/branch-names#290</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/289">tj-actions/branch-names#289</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/291">tj-actions/branch-names#291</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/292">tj-actions/branch-names#292</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/293">tj-actions/branch-names#293</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/294">tj-actions/branch-names#294</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/295">tj-actions/branch-names#295</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/296">tj-actions/branch-names#296</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/297">tj-actions/branch-names#297</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/298">tj-actions/branch-names#298</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/299">tj-actions/branch-names#299</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/300">tj-actions/branch-names#300</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/301">tj-actions/branch-names#301</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/302">tj-actions/branch-names#302</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/303">tj-actions/branch-names#303</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/304">tj-actions/branch-names#304</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/305">tj-actions/branch-names#305</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/306">tj-actions/branch-names#306</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/307">tj-actions/branch-names#307</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/308">tj-actions/branch-names#308</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/309">tj-actions/branch-names#309</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/310">tj-actions/branch-names#310</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/311">tj-actions/branch-names#311</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/312">tj-actions/branch-names#312</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/313">tj-actions/branch-names#313</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/314">tj-actions/branch-names#314</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/315">tj-actions/branch-names#315</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/316">tj-actions/branch-names#316</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/317">tj-actions/branch-names#317</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/318">tj-actions/branch-names#318</a></li>
<li>chore(deps): update actions/checkout digest to b4ffde6 by <a
href="https://github.com/renovate"><code>@​renovate</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/319">tj-actions/branch-names#319</a></li>
<li>Bump actions/checkout from 4.1.1 to 4.1.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/tj-actions/branch-names/pull/320">tj-actions/branch-names#320</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/branch-names/blob/main/HISTORY.md">tj-actions/branch-names's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/branch-names/compare/v8.0.2...v8.1.0">8.1.0</a>
- (2025-03-23)</h1>
<h2><!-- raw HTML omitted -->🚀 Features</h2>
<ul>
<li>Add support for strip_branch_prefix (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/406">#406</a>)
(<a
href="https://github.com/tj-actions/branch-names/commit/c83c87ab5379a8ff88c905ea78c391c0d53972ac">c83c87a</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/408">#408</a>)</li>
</ul>
<p>(<a
href="https://github.com/tj-actions/branch-names/commit/d18e657ed32f367301fdebeb9a88b7e5539f3052">d18e657</a>)
- (Tonye Jack)</p>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li>Update test.yml (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/409">#409</a>)
(<a
href="https://github.com/tj-actions/branch-names/commit/f44339b51f74753b57583fbbd124e18a81170ab1">f44339b</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->⬆️ Upgrades</h2>
<ul>
<li>Upgraded from v8.0.1 -&gt; v8.0.2 (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/407">#407</a>)</li>
</ul>
<p>(<a
href="https://github.com/tj-actions/branch-names/commit/86aaf170e74d8cad1e7d4f566f2e9bed6cf000af">86aaf17</a>)
- (Tonye Jack)</p>
<h1><a
href="https://github.com/tj-actions/branch-names/compare/v8.0.1...v8.0.2">8.0.2</a>
- (2025-03-15)</h1>
<h2><!-- raw HTML omitted -->📦 Bumps</h2>
<ul>
<li>Bump actions/checkout from 4.1.1 to 4.1.2</li>
</ul>
<p>Bumps <a
href="https://github.com/actions/checkout">actions/checkout</a> from
4.1.1 to 4.1.2.</p>
<ul>
<li><a href="https://github.com/actions/checkout/releases">Release
notes</a></li>
<li><a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">Changelog</a></li>
<li><a
href="https://github.com/actions/checkout/compare/v4.1.1...9bb56186c3b09b4f86b1c65136769dd318469633">Commits</a></li>
</ul>
<hr />
<p>updated-dependencies:</p>
<ul>
<li>dependency-name: actions/checkout
dependency-type: direct:production
update-type: version-update:semver-patch
...</li>
</ul>
<p>Signed-off-by: dependabot[bot] <a
href="mailto:support@github.com">support@github.com</a> (<a
href="https://github.com/tj-actions/branch-names/commit/534653b2272678c76b23f2e681c8cfc2056d7b99">534653b</a>)
- (dependabot[bot])</p>
<ul>
<li>Bump actions/checkout from 4.1.1 to 4.1.2</li>
</ul>
<p>Bumps <a
href="https://github.com/actions/checkout">actions/checkout</a> from
4.1.1 to 4.1.2.</p>
<ul>
<li><a href="https://github.com/actions/checkout/releases">Release
notes</a></li>
<li><a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">Changelog</a></li>
<li><a
href="https://github.com/actions/checkout/compare/v4.1.1...9bb56186c3b09b4f86b1c65136769dd318469633">Commits</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/branch-names/commit/f44339b51f74753b57583fbbd124e18a81170ab1"><code>f44339b</code></a>
chore: Update test.yml (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/409">#409</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/d18e657ed32f367301fdebeb9a88b7e5539f3052"><code>d18e657</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/408">#408</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/c83c87ab5379a8ff88c905ea78c391c0d53972ac"><code>c83c87a</code></a>
feat: add support for strip_branch_prefix (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/406">#406</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/86aaf170e74d8cad1e7d4f566f2e9bed6cf000af"><code>86aaf17</code></a>
Upgraded from v8.0.1 -&gt; v8.0.2 (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/407">#407</a>)</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/394802c2335dc81582b3569322f3d7da41a9978e"><code>394802c</code></a>
Deleted renovate.json</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/32798b2266752bb2b274d694923596fdc67c399a"><code>32798b2</code></a>
chore(deps): update actions/checkout action to v4.2.2</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/9a04c058bb2ddc036c2d273df7a6a21d42f28533"><code>9a04c05</code></a>
chore(deps): update actions/checkout digest to 11bd719</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/e400ca0ec8ef23d62fca0f9492fc40093a3f1012"><code>e400ca0</code></a>
chore(deps): update actions/checkout digest to eef6144</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/5d79051f9e52a0067942d0b42e53ca411220c07b"><code>5d79051</code></a>
chore(deps): update actions/checkout action to v4.2.1</li>
<li><a
href="https://github.com/tj-actions/branch-names/commit/d353900ec68b69229ad98021a530af33c416dcb1"><code>d353900</code></a>
chore(deps): update actions/checkout digest to 692973e (<a
href="https://redirect.github.com/tj-actions/branch-names/issues/394">#394</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tj-actions/branch-names/compare/6871f53176ad61624f978536bbf089c574dc19a2...f44339b51f74753b57583fbbd124e18a81170ab1">compare
view</a></li>
</ul>
</details>
<br />

Updates `github/codeql-action` from 3.28.11 to 3.28.12
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.28.12</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.12 - 19 Mar 2025</h2>
<ul>
<li>Dependency caching should now cache more dependencies for Java
<code>build-mode: none</code> extractions. This should speed up
workflows and avoid inconsistent alerts in some cases.</li>
<li>Update default CodeQL bundle version to 2.20.7. <a
href="https://redirect.github.com/github/codeql-action/pull/2810">#2810</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.12/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.28.12 - 19 Mar 2025</h2>
<ul>
<li>Dependency caching should now cache more dependencies for Java
<code>build-mode: none</code> extractions. This should speed up
workflows and avoid inconsistent alerts in some cases.</li>
<li>Update default CodeQL bundle version to 2.20.7. <a
href="https://redirect.github.com/github/codeql-action/pull/2810">#2810</a></li>
</ul>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<h2>3.28.10 - 21 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.5. <a
href="https://redirect.github.com/github/codeql-action/pull/2772">#2772</a></li>
<li>Address an issue where the CodeQL Bundle would occasionally fail to
decompress on macOS. <a
href="https://redirect.github.com/github/codeql-action/pull/2768">#2768</a></li>
</ul>
<h2>3.28.9 - 07 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.4. <a
href="https://redirect.github.com/github/codeql-action/pull/2753">#2753</a></li>
</ul>
<h2>3.28.8 - 29 Jan 2025</h2>
<ul>
<li>Enable support for Kotlin 2.1.10 when running with CodeQL CLI
v2.20.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2744">#2744</a></li>
</ul>
<h2>3.28.7 - 29 Jan 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.6 - 27 Jan 2025</h2>
<ul>
<li>Re-enable debug artifact upload for CLI versions 2.20.3 or greater.
<a
href="https://redirect.github.com/github/codeql-action/pull/2726">#2726</a></li>
</ul>
<h2>3.28.5 - 24 Jan 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2717">#2717</a></li>
</ul>
<h2>3.28.4 - 23 Jan 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.3 - 22 Jan 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2707">#2707</a></li>
<li>Fix an issue downloading the CodeQL Bundle from a GitHub Enterprise
Server instance which occurred when the CodeQL Bundle had been synced to
the instance using the <a
href="https://github.com/github/codeql-action-sync-tool">CodeQL Action
sync tool</a> and the Actions runner did not have Zstandard installed.
<a
href="https://redirect.github.com/github/codeql-action/pull/2710">#2710</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/5f8171a638ada777af81d42b55959a643bb29017"><code>5f8171a</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2814">#2814</a>
from github/update-v3.28.12-6349095d1</li>
<li><a
href="https://github.com/github/codeql-action/commit/bb59f7707d836b040802dbdf2ad1a16482d319da"><code>bb59f77</code></a>
Update changelog for v3.28.12</li>
<li><a
href="https://github.com/github/codeql-action/commit/6349095d19ec30397ffb02a63b7aa4f867deb563"><code>6349095</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2810">#2810</a>
from github/update-bundle/codeql-bundle-v2.20.7</li>
<li><a
href="https://github.com/github/codeql-action/commit/d7d03fda1241f6b0b3fae460c9f19c6e887158ad"><code>d7d03fd</code></a>
Add changelog note</li>
<li><a
href="https://github.com/github/codeql-action/commit/4e3a5342c5e8e627915b9a29b363f49da8c4a32e"><code>4e3a534</code></a>
Update default bundle to codeql-bundle-v2.20.7</li>
<li><a
href="https://github.com/github/codeql-action/commit/55f023701cfc1e7d11ef2ae0c5ec3193dae4fce4"><code>55f0237</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2802">#2802</a>
from github/mbg/dependency-caching/java-buildless</li>
<li><a
href="https://github.com/github/codeql-action/commit/6a151cd77488e58567da1dcf953e7aeeaca4950c"><code>6a151cd</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2811">#2811</a>
from github/dependabot/github_actions/actions-c2c311...</li>
<li><a
href="https://github.com/github/codeql-action/commit/7866bcdb1b15b5d5cba0021b87f36d9f6d977156"><code>7866bcd</code></a>
Manually bump workflow to match autogenerated file</li>
<li><a
href="https://github.com/github/codeql-action/commit/611289e0b0ce1f6fc14820f1b72edaed2de4ba2c"><code>611289e</code></a>
build(deps): bump ruby/setup-ruby in the actions group</li>
<li><a
href="https://github.com/github/codeql-action/commit/4c409a5b664afa7d5b12cd8487e310f286487472"><code>4c409a5</code></a>
Remove temporary dependency directory in <code>analyze</code> post
action</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/6bb031afdd8eb862ea3fc1848194185e076637e5...5f8171a638ada777af81d42b55959a643bb29017">compare
view</a></li>
</ul>
</details>
<br />

Updates `beatlabs/delete-old-branches-action` from 0.0.10 to 0.0.11
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/beatlabs/delete-old-branches-action/releases">beatlabs/delete-old-branches-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.0.11</h2>
<h2>What's Changed</h2>
<ul>
<li>chore: update readme by <a
href="https://github.com/Edgaraszs"><code>@​Edgaraszs</code></a> in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/36">beatlabs/delete-old-branches-action#36</a></li>
<li>fix: retrieve all branches through pagination by <a
href="https://github.com/nikaro"><code>@​nikaro</code></a> in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/38">beatlabs/delete-old-branches-action#38</a></li>
<li>fix: apply shellcheck recommandations by <a
href="https://github.com/nikaro"><code>@​nikaro</code></a> in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/37">beatlabs/delete-old-branches-action#37</a></li>
<li>fix: bump versions by <a
href="https://github.com/Edgaraszs"><code>@​Edgaraszs</code></a> in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/40">beatlabs/delete-old-branches-action#40</a></li>
<li>Sort tags via semver to preserve newest tags by <a
href="https://github.com/ecdemis123"><code>@​ecdemis123</code></a> in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/42">beatlabs/delete-old-branches-action#42</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Edgaraszs"><code>@​Edgaraszs</code></a>
made their first contribution in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/36">beatlabs/delete-old-branches-action#36</a></li>
<li><a href="https://github.com/nikaro"><code>@​nikaro</code></a> made
their first contribution in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/38">beatlabs/delete-old-branches-action#38</a></li>
<li><a
href="https://github.com/ecdemis123"><code>@​ecdemis123</code></a> made
their first contribution in <a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/pull/42">beatlabs/delete-old-branches-action#42</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/beatlabs/delete-old-branches-action/compare/v0.0.10...v0.0.11">https://github.com/beatlabs/delete-old-branches-action/compare/v0.0.10...v0.0.11</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/beatlabs/delete-old-branches-action/commit/4eeeb8740ff8b3cb310296ddd6b43c3387734588"><code>4eeeb87</code></a>
sort tags via semver (<a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/issues/42">#42</a>)</li>
<li><a
href="https://github.com/beatlabs/delete-old-branches-action/commit/1e32837fd650c9749fe7c36701f4ae6774639f40"><code>1e32837</code></a>
fix: bump versions (<a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/issues/40">#40</a>)</li>
<li><a
href="https://github.com/beatlabs/delete-old-branches-action/commit/3dd382723bf794a122239bc1d6b0116662d5ec0f"><code>3dd3827</code></a>
fix: apply shellcheck recommandations (<a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/issues/37">#37</a>)</li>
<li><a
href="https://github.com/beatlabs/delete-old-branches-action/commit/3a54bdf0f3658e31347dde33ff983b11fab69c7b"><code>3a54bdf</code></a>
fix: retrieve all branches through pagination (<a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/issues/38">#38</a>)</li>
<li><a
href="https://github.com/beatlabs/delete-old-branches-action/commit/3aac1083bb9bf5d1111a27300a1b3891b0a68dce"><code>3aac108</code></a>
chore: update readme (<a
href="https://redirect.github.com/beatlabs/delete-old-branches-action/issues/36">#36</a>)</li>
<li>See full diff in <a
href="https://github.com/beatlabs/delete-old-branches-action/compare/6e94df089372a619c01ae2c2f666bf474f890911...4eeeb8740ff8b3cb310296ddd6b43c3387734588">compare
view</a></li>
</ul>
</details>
<br />

Updates `umbrelladocs/action-linkspector` from 1.2.5 to 1.3.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/umbrelladocs/action-linkspector/releases">umbrelladocs/action-linkspector's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.3.2</h2>
<p>v1.3.2: PR <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/40">#40</a>
- Update linkspector version to 0.4.2</p>
<h2>Release v1.3.1</h2>
<p>v1.3.1: PR <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/38">#38</a>
- Add support for showing stats</p>
<h2>Release v1.3.0</h2>
<p>v1.3.0: PR <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/37">#37</a>
- Update linkspector version to 0.4.1</p>
<h2>What's Changed</h2>
<ul>
<li>Update linkspector version to 0.4.1 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>
in <a
href="https://redirect.github.com/UmbrellaDocs/action-linkspector/pull/37">UmbrellaDocs/action-linkspector#37</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/UmbrellaDocs/action-linkspector/compare/v1.2...v1.3.0">https://github.com/UmbrellaDocs/action-linkspector/compare/v1.2...v1.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/49cf4f8da82db70e691bb8284053add5028fa244"><code>49cf4f8</code></a>
Merge pull request <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/40">#40</a>
from UmbrellaDocs/update-linkspector-version</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/fb49f30059a34b9bfab39967511559fef398f2c1"><code>fb49f30</code></a>
Update linkspector version to 0.4.2</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/c6d4525e9f50b27a0e78fc42b537141058d034ef"><code>c6d4525</code></a>
Merge pull request <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/38">#38</a>
from UmbrellaDocs/stats</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/c311faff00cc2318a96e3cb41e1fc7dba4dffffd"><code>c311faf</code></a>
Add support for showing stats</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/808d98be382b6e1f97bd3dfa6aa85b4410769dc6"><code>808d98b</code></a>
Merge pull request <a
href="https://redirect.github.com/umbrelladocs/action-linkspector/issues/37">#37</a>
from UmbrellaDocs/update-linkspector-version</li>
<li><a
href="https://github.com/UmbrellaDocs/action-linkspector/commit/3935e7368cfeff39766dbcd3b514cbc3ff90df4c"><code>3935e73</code></a>
Update linkspector version to 0.4.1</li>
<li>See full diff in <a
href="https://github.com/umbrelladocs/action-linkspector/compare/de84085e0f51452a470558693d7d308fbb2fa261...49cf4f8da82db70e691bb8284053add5028fa244">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-24 12:25:03 +00:00
Spike Curtis e0ecc28638 feat: add telemetry to user-scoped tailnet API call (#17065)
Adds support for sending telemetry on calls to the User-scoped tailnet RPC endpoint. This is currently used only by Coder Desktop.

Later PRs will fill in the version, OS information, and device ID via HTTP headers.
2025-03-24 16:02:33 +04:00
Mathias Fredriksson 6bf22f8dc6 fix(Makefile): fix dcspec gen dependencies and hide error output (#17043) 2025-03-24 11:41:45 +00:00
Danielle Maywood 765e7058e8 chore: use container memory if containerised for oom notifications (#17062)
Currently we query only the underlying host's memory usage for our
memory resource monitor. This PR changes that to check if the workspace
is in a container, and if so it queries the container's memory usage,
falling back to the host's memory usage if not.
2025-03-24 11:14:21 +00:00
Cian Johnston 674f60fc5b fix(cli): replace $SESSION_TOKEN placeholder for external apps (#17048)
Fixes an oversight in https://github.com/coder/coder/pull/17032

The FE has logic to replace the string `$SESSION_TOKEN` with a
newly-minted session token.
This adds corresponding logic to the `coder open app` command.
2025-03-24 09:03:30 +00:00
Dean Sheather 77fe10ead8 chore(dogfood): update EU server from Helsinki to Falkenstein (#17061) 2025-03-24 02:22:34 +11:00
Dean Sheather 60c4944503 chore: bump golang to 1.22.12 (#17058) 2025-03-22 00:58:09 +00:00
dependabot[bot] 5c30806db6 chore: bump next from 14.2.23 to 14.2.25 in /offlinedocs (#17055)
Bumps [next](https://github.com/vercel/next.js) from 14.2.23 to 14.2.25.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/next.js/releases">next's
releases</a>.</em></p>
<blockquote>
<h2>v14.2.25</h2>
<blockquote>
<p>[!NOTE]<br />
This release is backporting bug fixes. It does <strong>not</strong>
include all pending features/changes on canary.
This release contains a security patch for <a
href="https://github.com/vercel/next.js/security/advisories/GHSA-f82v-jwr5-mffw">CVE-2025-29927</a>.</p>
</blockquote>
<h3>Core Changes</h3>
<ul>
<li>Update middleware request header (<a
href="https://redirect.github.com/vercel/next.js/issues/77202">#77202</a>)</li>
</ul>
<h3>Credits</h3>
<p>Huge thanks to <a
href="https://github.com/ijjk"><code>@​ijjk</code></a> for helping!</p>
<h2>v14.2.24</h2>
<blockquote>
<p>[!NOTE]<br />
This release is backporting bug fixes. It does <strong>not</strong>
include all pending features/changes on canary.</p>
</blockquote>
<h3>Core Changes</h3>
<ul>
<li>fix: ensure lint worker errors aren't silenced (<a
href="https://redirect.github.com/vercel/next.js/issues/75779">#75779</a>)</li>
<li>add additional x-middleware-set-cookie filtering (<a
href="https://redirect.github.com/vercel/next.js/issues/75561">#75561</a>
&amp; <a
href="https://redirect.github.com/vercel/next.js/issues/73482">#73482</a>)</li>
</ul>
<h3>Credits</h3>
<p>Huge thanks to <a
href="https://github.com/ztanner"><code>@​ztanner</code></a> for
helping!</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/next.js/commit/d36a1f3c3547b0cb807f30c14aa6250a932349c8"><code>d36a1f3</code></a>
v14.2.25</li>
<li><a
href="https://github.com/vercel/next.js/commit/5fd3ae8f8542677c6294f32d18022731eab6fe48"><code>5fd3ae8</code></a>
[backport] Update middleware request header (<a
href="https://redirect.github.com/vercel/next.js/issues/77202">#77202</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/756be15c4cfecb6fae1c69cae7cfaf336423b6cf"><code>756be15</code></a>
v14.2.24</li>
<li><a
href="https://github.com/vercel/next.js/commit/ba6453d5efbb1dcb282c39d372b48d60de59fa2c"><code>ba6453d</code></a>
fix corepack keys</li>
<li><a
href="https://github.com/vercel/next.js/commit/c482c2072f6eb3f7bd656bc05e100ed54dce3636"><code>c482c20</code></a>
[backport v14] fix: ensure lint worker errors aren't silenced (<a
href="https://redirect.github.com/vercel/next.js/issues/75766">#75766</a>)
(<a
href="https://redirect.github.com/vercel/next.js/issues/75779">#75779</a>)</li>
<li><a
href="https://github.com/vercel/next.js/commit/5791cb677808df1cea625057d6aff95fbf5cd3a0"><code>5791cb6</code></a>
[Backport v14] add additional x-middleware-set-cookie filtering (<a
href="https://redirect.github.com/vercel/next.js/issues/75561">#75561</a>)
(<a
href="https://redirect.github.com/vercel/next.js/issues/75">#75</a>...</li>
<li><a
href="https://github.com/vercel/next.js/commit/8129a6188096c23c68d4151256acbe6d86d2eed3"><code>8129a61</code></a>
test: fix eslint plugin test (<a
href="https://redirect.github.com/vercel/next.js/issues/75687">#75687</a>)</li>
<li>See full diff in <a
href="https://github.com/vercel/next.js/compare/v14.2.23...v14.2.25">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=next&package-manager=npm_and_yarn&previous-version=14.2.23&new-version=14.2.25)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-21 22:47:05 +00:00
dependabot[bot] 17fe7f6ea2 chore: bump github.com/golang-jwt/jwt/v4 from 4.5.1 to 4.5.2 (#17054)
Bumps [github.com/golang-jwt/jwt/v4](https://github.com/golang-jwt/jwt)
from 4.5.1 to 4.5.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/golang-jwt/jwt/releases">github.com/golang-jwt/jwt/v4's
releases</a>.</em></p>
<blockquote>
<h2>v4.5.2</h2>
<p>See <a
href="https://github.com/golang-jwt/jwt/security/advisories/GHSA-mh63-6h87-95cp">https://github.com/golang-jwt/jwt/security/advisories/GHSA-mh63-6h87-95cp</a></p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/golang-jwt/jwt/compare/v4.5.1...v4.5.2">https://github.com/golang-jwt/jwt/compare/v4.5.1...v4.5.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang-jwt/jwt/commit/2f0e9add62078527821828c76865661aa7718a84"><code>2f0e9ad</code></a>
Backporting 0951d18 to v4</li>
<li>See full diff in <a
href="https://github.com/golang-jwt/jwt/compare/v4.5.1...v4.5.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/golang-jwt/jwt/v4&package-manager=go_modules&previous-version=4.5.1&new-version=4.5.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-21 22:41:03 +00:00
Bruno Quaresma e40ea258dc fix: fix double ws connection for notifications (#17044)
**Issue:**
The UI was creating two web socket connections to receive notification
updates causing duplicated values.

**Cause:**
We were rendering the notification container twice. One for the desktop
nav and another for mobile.

**Fix:**
Only use one notification container for the nav.

**Improvements for later:**
I think would be better at some point to move the networking and data
logic into a provider but it would require testing and some tiny rework.
Since the actual fix works well, and it is not complex or difficult, I
think it is ok to stay with it until we require to load notifications in
more places.
2025-03-21 14:12:22 -03:00
Bruno Quaresma 1593861d7c feat: add load more notifications on inbox (#17030)
Users need to see older notifications, so to make that happen, we added
a load more button at the end of the notifications list.

**Demo:**


https://github.com/user-attachments/assets/bd3d7964-a8f5-4164-8da0-9ba89ae88c9c

**What is missing?**
As you can notice, I didn't add tests for this feature. I tried, but I
didn't find a good solution for testing scroll events. However I was
able to get it working, but it was too cumbersome that I decided to
remove because of its maintenence burden.
2025-03-21 13:38:17 -03:00
Vincent Vielle 82e37732ea feat(coderd): add format option to inbox notifications watch endpoint (#17034)
This PR aims to allow clients to use different format for the title and
content of inbox notifications - on the watch endpoint.

This solution will help to have it working and formatted differently on
VSCode, WebUI ...
[Related to this issue](https://github.com/coder/internal/issues/523)
2025-03-21 16:41:13 +01:00
Cian Johnston 0474888eb4 feat(cli): add open app <workspace> <app-slug> command (#17032)
Fixes https://github.com/coder/coder/issues/17009

Adds a CLI command `coder open app <workspace> <app-slug>` that allows
opening arbitrary `coder_apps` via the CLI.

Users can optionally specify a region for workspace
applications.
2025-03-21 15:28:08 +00:00
Mathias Fredriksson 3b6bee9676 chore(Makefile): fix apidoc dependencies (#17042)
Our apidoc generation had some circular dependencies, this change splits
them up into separate Makefile targets.
2025-03-21 17:16:17 +02:00
Vincent Vielle fe24a7a4a8 feat(coderd): remove greetings from notifications templates (#16991)
This PR aimes to [fix this
issue](https://github.com/coder/internal/issues/448) -

The main idea is to remove greetings from templates stored in the DB -
and instead push it into the template for require methods - for now
SMTP.
2025-03-21 16:05:08 +01:00
Edward Angert bbe7dacd35 docs: document definition of workspace activity (#16941)
closes: https://github.com/coder/coder/issues/16884

aligns the documentation with what users see when they adjust settings
and uses the [notion
discussion](https://www.notion.so/coderhq/Definitions-of-Workspace-Usage-Autostop-Dormancy-e7fa8ff782a948c19bbe4ef8315c26cb)
as a reference. This PR reflects current behavior from what I can tell.


[preview](https://coder.com/docs/@16884-define-activity/user-guides/workspace-scheduling#activity-detection)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-21 10:36:24 -04:00
Mathias Fredriksson f4b6f429c6 chore(Makefile): fix dependencies and timestamps (#17040)
This change should reduce "infinite" dependency cycles.

I added some unnecessary `touch`es for completeness.
2025-03-21 15:33:07 +02:00
Cian Johnston 6908c1b2b7 chore: linkspector ignore mutagen.io (#17041) 2025-03-21 13:18:19 +00:00
Mathias Fredriksson b79167293c chore(Makefile): update golden files as part of make gen (#17039)
Updating golden files is an unnecessary extra step in addition to gen
that is easily overlooked, leading to the developer noticing the issue
in CI leading to lost developer time waiting for tests to complete.
2025-03-21 13:04:30 +00:00
Hugo Dutka de6080c46d chore: update comment on the users.github_com_user_id field (#17037)
Follow up to https://github.com/coder/coder/pull/17029.
2025-03-21 13:31:17 +01:00
Hugo Dutka a71aa202dc feat: filter users by github user id in the users list CLI command (#17029)
Add the `--github-user-id` option to `coder users list`, which makes the
command only return users with a matching GitHub user id. This will
enable https://github.com/coder/start-workspace-action to find a Coder
user that corresponds to a GitHub user requesting to start a workspace.
2025-03-21 13:30:47 +01:00
Mathias Fredriksson 69ba27e347 feat: allow specifying devcontainer on agent in terraform (#16997)
This change allows specifying devcontainers in terraform and plumbs it
through to the agent via agent manifest.

This will be used for autostarting devcontainers in a workspace.

Depends on coder/terraform-provider-coder#368
Updates #16423
2025-03-20 19:09:39 +02:00
Marcin Tojek 287e3198d8 fix: use navigator.locale to evaluate time format (#17025)
Fixes: https://github.com/coder/coder/issues/15452
2025-03-20 15:53:03 +01:00
Cian Johnston 3bd32a2e2a chore(cli): wait for agent to connect before dialing it in TestExpRpty (#17026)
Fixes flake seen here:
https://github.com/coder/coder/actions/runs/13970861685/job/39113344525
2025-03-20 14:44:30 +00:00
Mathias Fredriksson 72d9876c76 fix(coderd/workspaceapps): prevent race in workspace app audit session updates (#17020)
Fixes coder/internal#520
2025-03-20 14:10:45 +00:00
Cian Johnston 68624092a4 feat(agent/reconnectingpty): allow selecting backend type (#17011)
agent/reconnectingpty: allow specifying backend type
cli: exp rpty: automatically select backend based on command
2025-03-20 13:45:31 +00:00
Bruno Quaresma 0cd254f219 feat: enable mark all inbox notifications as read (#17023)
Bind the "Mark all notifications as read" action to the correct API
request in the UI.
2025-03-20 10:30:05 -03:00
Hugo Dutka 8d5e6f3cc0 fix: fix IsGithubDotComURL check (#17022)
When DeviceFlow with GitHub OAuth2 is configured, the
`api.GithubOAuth2Config.AuthCode` is
[overridden](https://github.com/coder/coder/blob/b08c8c9e1ee8edf18e9ba575098d99533062a240/coderd/userauth.go#L779)
and returns a value that doesn't pass the `IsGithubDotComURL` check.
This PR ensures the original `AuthCodeURL` method is used instead.
2025-03-20 13:24:38 +00:00
Spike Curtis 7d60186b7e feat: add user_tailnet_connections to telemetry (#17018)
## Summary
- Add UserTailnetConnection struct to track desktop client connections
- Add new field to Snapshot struct for telemetry
- Data collection to be implemented in a future PR

relates to coder/nexus#197
2025-03-20 17:04:43 +04:00
Bruno Quaresma bf59c7ca0f fix: add notifications back to desktop (#17021)
The notifications were removed on [this PR
](https://github.com/coder/coder/pull/17008)by accident.
2025-03-20 09:42:08 -03:00
Vincent Vielle 4960a1e85a feat(coderd): add mark-all-as-read endpoint for inbox notifications (#16976)
[Resolve this issue](https://github.com/coder/internal/issues/506)

Add a mark-all-as-read endpoint which is marking as read all
notifications that are not read for the authenticated user.
Also adds the DB logic.
2025-03-20 13:41:54 +01:00
Marcin Tojek d8d4b9b86e feat: display quiet hours using 24-hour time format (#17016)
Fixes: https://github.com/coder/coder/issues/15452
2025-03-20 10:40:42 +01:00
Sas Swart 38b21ab35d fix(site): gracefully handle reselection of the same preset (#17014)
This PR closes https://github.com/coder/coder/issues/16953.

Reselecting a preset that was already the selected preset returned an
undefined option to the onSelect function. We then tried to read an
attribute of this undefined value. With this fix, we handle the
undefined option correctly.
2025-03-20 07:42:51 +00:00
Danielle Maywood b39477c07a fix: resolve flakey inbox tests (#17010) 2025-03-19 22:06:47 +00:00
Bruno Quaresma 4ea5ef925f feat: make notifications header sticky (#17005)
When having a bunch of notifications and the user is scrolling down the
content it is helpful to keep the header visible so the user can easily
mark all of them as read if they want to.
2025-03-19 16:02:45 -03:00
Edward Angert c88d86bf50 docs: add new doc on how to deploy Coder on Rancher (#16534)
[preview](https://coder.com/docs/@deploy-on-rancher/install/rancher)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-19 18:50:52 +00:00
Bruno Quaresma ab763ca242 fix: show notifications on mobile (#17008)
Show the notifications close to the menu button.

**After fix:**
<img width="515" alt="Screenshot 2025-03-19 at 15 09 36"
src="https://github.com/user-attachments/assets/38f86c5b-d324-4a8b-9c68-ea818b226ae4"
/>
2025-03-19 15:19:57 -03:00
Bruno Quaresma abbd88b819 feat: update notification badge to support 99+ (#17007)
After dogfooding the notifications we noticed that admins will probably
have a larger number of unread notifications everyday so with that in
mind we decided to increase the "truncate" rate from 9+ to 99+.
2025-03-19 15:15:31 -03:00
Hugo Dutka 6a7c43d76c chore: add the start workspace workflow (#17002)
The workflow triggers when an issue is created or a comment is posted.
If the string "@coder" appears in the body of the issue or comment, a
Coder workspace owned by the issue creator or commentator will be
created with the parameters specified in the workflow.
2025-03-19 12:39:37 -04:00
Edward Angert bd243c17fb docs: add AWS AMI upgrade instructions (#16973)
followup to @d1str0's #16937 

> Adds a small note for those who just used the AWS AMI for their
initial installation.

This PR rearranges the Upgrade doc to use tabs for each section + adds
AWS AMI

[preview](https://coder.com/docs/@upgrade-tabs/install/upgrade)

---------

Co-authored-by: Brady Sullivan <brady@bsull.com>
Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-19 10:10:58 -04:00
Bruno Quaresma 4a548021c3 fix: close popover when notification settings are clicked (#17001)
When a user clicks in the notification settings does not make sense to
keep the popover open, instead, we want to close it.
2025-03-19 10:52:04 -03:00
Bruno Quaresma 86d907126d fix: fix overflowing text in inbox notifications (#17000)
- Break white spaces 
- Break long words in inbox notifications

**Before:**
<img width="499" alt="Screenshot 2025-03-19 at 10 10 36"
src="https://github.com/user-attachments/assets/4729cf51-0e2c-412b-b5e5-bb37a4b7d86f"
/>

**Now:**
<img width="498" alt="Screenshot 2025-03-19 at 10 10 15"
src="https://github.com/user-attachments/assets/331e8492-0114-4100-bd46-a66258741e46"
/>
2025-03-19 10:39:37 -03:00
Mathias Fredriksson 3ac844ad3d chore(codersdk): rename WorkspaceAgent(Dev)container structs (#16996)
This is to free up the devcontainer name space for more targeted
structs.

Updates #16423
2025-03-19 10:16:14 +00:00
Danielle Maywood ef62e626c8 fix: ensure targets are propagated to inbox (#16985)
Currently the `targets` column in `inbox_notifications` doesn't get
filled. This PR fixes that. Rather than give targets special treatment,
we should put it in the payload like everything else. This correctly
propagates notification targets to the inbox table without much code
change.
2025-03-19 09:51:49 +00:00
ケイラ 995e9402b4 chore: don't autofocus OrganizationAutocomplete on user creation page (#16989) 2025-03-18 15:33:40 -06:00
Bruno Quaresma ab8ba96707 feat: add notifications widget in the navbar (#16983)
**Preview:**
<img width="479" alt="Screenshot 2025-03-18 at 10 38 25"
src="https://github.com/user-attachments/assets/2e4cb48e-3606-478c-a68d-13465789330b"
/>

[Figma
file](https://www.figma.com/design/5kRpzK8Qr1k38nNz7H0HSh/Inbox-notifications?node-id=1-2726&t=PUsQwLrwyzXUxhf1-0)

**This PR adds:**
- Notification widget in the navbar
- Show notifications
- Option to mark each notification as read
- Update notifications in realtime 

**What is next?**
- Option to mark all the notifications as read at once
- Option to load previous notifications - Right now, it only shows the
latest 25 notifications
- Having custom icons for each type of notification

**And about tests?**
The notification widget components are well covered by the current
stories, but we definitely want to have e2e tests for it. However, in my
recent projects, I found more useful to ship the UI features first, get
feedback, change whatever needs to be changed, and then, add the e2e
tests to avoid major rework.

Related to https://github.com/coder/internal/issues/336
2025-03-18 15:21:22 -03:00
ケイラ cb19fd47b0 chore: use user admin and template admin for even more e2e tests (#16974) 2025-03-18 09:11:39 -06:00
ケイラ 49a35e3784 chore: add e2e tests for organization auditors (#16899) 2025-03-18 09:10:42 -06:00
Cian Johnston 75b27e8f19 fix(agent/agentcontainers): improve testing of convertDockerInspect, return correct host port (#16887)
* Improves separation of concerns between `runDockerInspect` and
`convertDockerInspect`: `runDockerInspect` now just runs the command and
returns the output, while `convertDockerInspect` now does all of the
conversion and parsing logic.
* Improves testing of `convertDockerInspect` using real test fixtures.
* Fixes issue where the container port is returned instead of the host
port.
* Updates UI to link to correct host port. Container port is still
displayed in the button text, but the HostIP:HostPort is shown in a
popover.
* Adds stories for workspace agent UI
2025-03-18 14:37:45 +00:00
Marcin Tojek 13d0dac795 feat: display error if app is not installed (#16980)
Fixes: https://github.com/coder/coder/issues/13937
2025-03-18 14:24:02 +01:00
Cian Johnston 13a3ddd964 fix(agent/agentcontainers): generate devcontainer metadata from schema (#16881)
Adds new dcspec package containing automatically generated devcontainer schema (using glideapps/quicktype).
2025-03-18 13:00:21 +00:00
Danielle Maywood ec517657a8 chore: add targets to oom/ood notifications (#16968)
Add targets to OOM/OOD notifications to allow Coder Inbox clients to
filter on these notifications.
2025-03-18 12:59:30 +00:00
Sas Swart a3f6308006 fix: rewrite login type migrations (#16978)
When trying to add [system
users](https://github.com/coder/coder/pull/16916), we discovered an
issue in two migrations that added values to the login_type enum.
After some
[consideration](https://github.com/coder/coder/pull/16916#discussion_r1998758887),
we decided to retroactively correct them.
2025-03-18 14:47:30 +02:00
Mathias Fredriksson de41bd6b95 feat: add support for workspace app audit (#16801)
This change adds support for workspace app auditing.

To avoid audit log spam, we introduce the concept of app audit sessions.
An audit session is unique per workspace app, user, ip, user agent and
http status code. The sessions are stored in a separate table from audit
logs to allow use-case specific optimizations. Sessions are ephemeral
and the table does not function as a log.

The logic for auditing is placed in the DBTokenProvider for workspace
apps so that wsproxies are included.

This is the final change affecting the API fo #15139.

Updates #15139
2025-03-18 13:50:52 +02:00
Vincent Vielle 3ae55bbbf4 feat(coderd): add inbox notifications endpoints (#16889)
This PR is part of the inbox notifications topic, and rely on previous
PRs merged - it adds :

- Endpoints to : 
  - WS : watch new inbox notifications
  - REST : list inbox notifications
  - REST : update the read status of a notification

Also, this PR acts as a follow-up PR from previous work and : 

- fix DB query issues
- fix DBMem logic to match DB
2025-03-18 00:02:47 +01:00
brettkolodny e85c92e7d5 chore: remove the double confirmation when creating an organization via the CLI (#16972)
Closes
[coder/internal#476](https://github.com/coder/internal/issues/476)
2025-03-17 17:14:59 -04:00
Edward Angert 8ca52a835e docs: document steps for adding cert to JetBrains plugin settings (#16882)
- document the steps from @stirby in ticket
- separate the different OSs in a way that's easier to look at
- fix typo


[preview](https://coder.com/docs/@593-ca-cert-plugin/user-guides/workspace-access/jetbrains#configuring-the-gateway-plugin-to-use-internal-certificates)

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-17 17:11:36 -04:00
rohansinha01 83f1d82b45 fix: update WorkspacesEmpty.tsx from material ui to tailwind (#16886) 2025-03-17 10:51:31 -06:00
dependabot[bot] 27a160d136 ci: bump the github-actions group with 4 updates (#16966)
Bumps the github-actions group with 4 updates:
[docker/login-action](https://github.com/docker/login-action),
[tj-actions/changed-files](https://github.com/tj-actions/changed-files),
[nix-community/cache-nix-action](https://github.com/nix-community/cache-nix-action)
and
[aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action).

Updates `docker/login-action` from 3.3.0 to 3.4.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/login-action/releases">docker/login-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.4.0</h2>
<ul>
<li>Bump <code>@​actions/core</code> from 1.10.1 to 1.11.1 in <a
href="https://redirect.github.com/docker/login-action/pull/791">docker/login-action#791</a></li>
<li>Bump <code>@​aws-sdk/client-ecr</code> to 3.766.0 in <a
href="https://redirect.github.com/docker/login-action/pull/789">docker/login-action#789</a>
<a
href="https://redirect.github.com/docker/login-action/pull/856">docker/login-action#856</a></li>
<li>Bump <code>@​aws-sdk/client-ecr-public</code> to 3.758.0 in <a
href="https://redirect.github.com/docker/login-action/pull/789">docker/login-action#789</a>
<a
href="https://redirect.github.com/docker/login-action/pull/856">docker/login-action#856</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.35.0 to 0.57.0 in
<a
href="https://redirect.github.com/docker/login-action/pull/801">docker/login-action#801</a>
<a
href="https://redirect.github.com/docker/login-action/pull/806">docker/login-action#806</a>
<a
href="https://redirect.github.com/docker/login-action/pull/858">docker/login-action#858</a></li>
<li>Bump cross-spawn from 7.0.3 to 7.0.6 in <a
href="https://redirect.github.com/docker/login-action/pull/814">docker/login-action#814</a></li>
<li>Bump https-proxy-agent from 7.0.5 to 7.0.6 in <a
href="https://redirect.github.com/docker/login-action/pull/823">docker/login-action#823</a></li>
<li>Bump path-to-regexp from 6.2.2 to 6.3.0 in <a
href="https://redirect.github.com/docker/login-action/pull/777">docker/login-action#777</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/login-action/compare/v3.3.0...v3.4.0">https://github.com/docker/login-action/compare/v3.3.0...v3.4.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/login-action/commit/74a5d142397b4f367a81961eba4e8cd7edddf772"><code>74a5d14</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/856">#856</a>
from docker/dependabot/npm_and_yarn/aws-sdk-dependenc...</li>
<li><a
href="https://github.com/docker/login-action/commit/2f4f00e4c6fe8a50cdd1fd618421be2e92b2f201"><code>2f4f00e</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/login-action/commit/67c184546cf989af16f02a1b5359e4bde3cdc524"><code>67c1845</code></a>
build(deps): bump the aws-sdk-dependencies group across 1 directory with
2 up...</li>
<li><a
href="https://github.com/docker/login-action/commit/3d4cc89e85e0cac73870ab81d3b72c0b700870d1"><code>3d4cc89</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/844">#844</a>
from graysonpike/master</li>
<li><a
href="https://github.com/docker/login-action/commit/6cc823a6c4738f797f031790fa7f982b7a8dcfdc"><code>6cc823a</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/823">#823</a>
from docker/dependabot/npm_and_yarn/proxy-agent-depen...</li>
<li><a
href="https://github.com/docker/login-action/commit/d94e792124647378e94c07359922f0f821a9fab2"><code>d94e792</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/login-action/commit/033db0da3047b4d01e249d66f56ae16a2ed6af87"><code>033db0d</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/812">#812</a>
from docker/dependabot/github_actions/codecov/codecov...</li>
<li><a
href="https://github.com/docker/login-action/commit/09c2ae9716c0bacef3c03e120a61c28adfb8595b"><code>09c2ae9</code></a>
build(deps): bump https-proxy-agent</li>
<li><a
href="https://github.com/docker/login-action/commit/ba56f006fc7190f752d4e6e1312f85697984a229"><code>ba56f00</code></a>
ci: update deprecated input for codecov-action</li>
<li><a
href="https://github.com/docker/login-action/commit/75bf9a79af089e9aa009972a6ecb22190a520679"><code>75bf9a7</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/login-action/issues/858">#858</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/login-action/compare/9780b0c442fbb1117ed29e0efdff1e18412f7567...74a5d142397b4f367a81961eba4e8cd7edddf772">compare
view</a></li>
</ul>
</details>
<br />

Updates `tj-actions/changed-files` from
dcc7a0cba800f454d79fff4b993e8c3555bcc0a8 to
531f5f7d163941f0c1c04e0ff4d8bb243ac4366f
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/tj-actions/changed-files/blob/main/HISTORY.md">tj-actions/changed-files's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v46.0.0...v46.0.1">46.0.1</a>
- (2025-03-16)</h1>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2473">#2473</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/2f7c5bfce28377bc069a65ba478de0a74aa0ca32">2f7c5bf</a>)
- (github-actions[bot])</p>
<ul>
<li>Sync-release-version.yml to use signed commits (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2472">#2472</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/4189ec62c445484531e9ad97157d990be96e88ee">4189ec6</a>)
- (Tonye Jack)</li>
</ul>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v45.0.9...v46.0.0">46.0.0</a>
- (2025-03-16)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li>Update update-readme.yml to sign-commits (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2468">#2468</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/0f1ffe61855cb317d5fd66122c14dc0627eab141">0f1ffe6</a>)
- (Tonye Jack)</li>
<li>Update permission in update-readme.yml workflow (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2467">#2467</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/ddef03e37c84cfb9ee89fa055b86359aaf949c86">ddef03e</a>)
- (Tonye Jack)</li>
<li>Update github workflow update-readme.yml (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2466">#2466</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/9c2df0d54a911c819d7368d7e5ed7c01c0796e0a">9c2df0d</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted --> Remove</h2>
<ul>
<li>Deleted renovate.json (<a
href="https://github.com/tj-actions/changed-files/commit/e37e952786556966c1fb6183c5937b3966bab099">e37e952</a>)
- (Tonye Jack)</li>
</ul>
<h2><!-- raw HTML omitted -->🔄 Update</h2>
<ul>
<li>Sync-release-version.yml (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2471">#2471</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/4cd184a1dd542b79cca1d4d7938e4154a6520ca7">4cd184a</a>)
- (Tonye Jack)</li>
<li>Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2469">#2469</a>)</li>
</ul>
<p>Co-authored-by: github-actions[bot] <!-- raw HTML omitted --> (<a
href="https://github.com/tj-actions/changed-files/commit/5cbf22026d05fbef0c027d1b1f118fe3a1b6e435">5cbf220</a>)
- (github-actions[bot])</p>
<h2><!-- raw HTML omitted -->📚 Documentation</h2>
<ul>
<li>Update docs to highlight security issues (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2465">#2465</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/65253327cf47481b4b1b4b9fea78e143a1353147">6525332</a>)
- (Tonye Jack)</li>
</ul>
<h1><a
href="https://github.com/tj-actions/changed-files/compare/v45.0.4...v45.0.9">45.0.9</a>
- (2025-03-15)</h1>
<h2><!-- raw HTML omitted -->🐛 Bug Fixes</h2>
<ul>
<li><strong>deps:</strong> Update dependency <code>@​octokit/rest</code>
to v21.1.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2435">#2435</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/fb8dcda5fb8954cec37773d2b275a8579c86c781">fb8dcda</a>)
- (renovate[bot])</li>
<li><strong>deps:</strong> Update dependency <code>@​octokit/rest</code>
to v21.1.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2394">#2394</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/7b72c97d739f955f5cadca0d59799d826ae9f6c9">7b72c97</a>)
- (renovate[bot])</li>
<li><strong>deps:</strong> Update dependency yaml to v2.7.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2383">#2383</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/5f974c28f5044c411f0c9e7becf3f172029cf9cf">5f974c2</a>)
- (renovate[bot])</li>
</ul>
<h2><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h2>
<ul>
<li><strong>deps:</strong> Lock file maintenance (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2460">#2460</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/9200e69727eb73eb060652b19946b8a2fdfb654b">9200e69</a>)
- (renovate[bot])</li>
<li><strong>deps:</strong> Update dependency <code>@​types/node</code>
to v22.13.10 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2459">#2459</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/e650cfdae513481a20f538e88d98b39106523006">e650cfd</a>)
- (renovate[bot])</li>
<li><strong>deps:</strong> Update dependency eslint-config-prettier to
v10.1.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2458">#2458</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/82af21f4a05896ca18c950539469bee225c45a89">82af21f</a>)
- (renovate[bot])</li>
<li><strong>deps:</strong> Update dependency eslint-config-prettier to
v10.1.0 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2457">#2457</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/82fa4a6402582d5c8c9c0e95b7ff7cc88992bbb4">82fa4a6</a>)
- (renovate[bot])</li>
<li><strong>deps:</strong> Update peter-evans/create-pull-request action
to v7.0.8 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2455">#2455</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/315505acf41d2913b71af48080fb158cd01f79e7">315505a</a>)
- (renovate[bot])</li>
<li><strong>deps:</strong> Update dependency <code>@​types/node</code>
to v22.13.9 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2454">#2454</a>)
(<a
href="https://github.com/tj-actions/changed-files/commit/c8e1cdb9ea135ee549963c167ffaec5e7d4a71cd">c8e1cdb</a>)
- (renovate[bot])</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/tj-actions/changed-files/commit/531f5f7d163941f0c1c04e0ff4d8bb243ac4366f"><code>531f5f7</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2479">#2479</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/dccd1949addfa3d93d458019c5495581c620b00c"><code>dccd194</code></a>
doc: update README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2478">#2478</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/9237eb7a0f95c801719e6224d45095d4dda0f9bd"><code>9237eb7</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2476">#2476</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/d52b942ee0c535798f0df9e1c05683f8e818c79b"><code>d52b942</code></a>
add hint to revoke leaked token (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2475">#2475</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/45fb12d7a8bedb4da42342e52fe054c6c2c3fd73"><code>45fb12d</code></a>
Upgraded to v46.0.1 (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2474">#2474</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/2f7c5bfce28377bc069a65ba478de0a74aa0ca32"><code>2f7c5bf</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2473">#2473</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/4189ec62c445484531e9ad97157d990be96e88ee"><code>4189ec6</code></a>
update: sync-release-version.yml to use signed commits (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2472">#2472</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/4cd184a1dd542b79cca1d4d7938e4154a6520ca7"><code>4cd184a</code></a>
update: sync-release-version.yml (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2471">#2471</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/5cbf22026d05fbef0c027d1b1f118fe3a1b6e435"><code>5cbf220</code></a>
Updated README.md (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2469">#2469</a>)</li>
<li><a
href="https://github.com/tj-actions/changed-files/commit/0f1ffe61855cb317d5fd66122c14dc0627eab141"><code>0f1ffe6</code></a>
fix: update update-readme.yml to sign-commits (<a
href="https://redirect.github.com/tj-actions/changed-files/issues/2468">#2468</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/tj-actions/changed-files/compare/dcc7a0cba800f454d79fff4b993e8c3555bcc0a8...531f5f7d163941f0c1c04e0ff4d8bb243ac4366f">compare
view</a></li>
</ul>
</details>
<br />

Updates `nix-community/cache-nix-action` from 6.1.1 to 6.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nix-community/cache-nix-action/releases">nix-community/cache-nix-action's
releases</a>.</em></p>
<blockquote>
<h2>v6.1.2</h2>
<h2>Fixes</h2>
<ul>
<li>Fix nix store database merging logic (<a
href="https://redirect.github.com/nix-community/cache-nix-action/pull/84">nix-community/cache-nix-action#84</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/c448f065ba14308da81de769632ca67a3ce67cf5"><code>c448f06</code></a>
Merge pull request <a
href="https://redirect.github.com/nix-community/cache-nix-action/issues/84">#84</a>
from nix-community/82-bug-v610-and-v611-dont-seem-to-w...</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/fc908ede39799ad79a606fe33e69e88457d34ebc"><code>fc908ed</code></a>
chore: build the action</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/57dad844a98b1a6324aa4453a8a8dc9625b1acc9"><code>57dad84</code></a>
chore: build the action</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/0d5803d685b779eaef4f25299f3df35ec63d995d"><code>0d5803d</code></a>
fix(action): print a message after the check</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/db360de0f846626dcb5183d838d0f1436d09c3c4"><code>db360de</code></a>
chore: build the action</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/07c1e7f98e139e19f4042ac93d7a36b68012fde7"><code>07c1e7f</code></a>
fix(action): join on the derivation path, not the output path</li>
<li><a
href="https://github.com/nix-community/cache-nix-action/commit/1b9cbefbf818ca652a08a9d1be8f18e7e2a244f7"><code>1b9cbef</code></a>
fix(action): parse gc-max-store-size correctly</li>
<li>See full diff in <a
href="https://github.com/nix-community/cache-nix-action/compare/aee88ae5efbbeb38ac5d9862ecbebdb404a19e69...c448f065ba14308da81de769632ca67a3ce67cf5">compare
view</a></li>
</ul>
</details>
<br />

Updates `aquasecurity/trivy-action` from 0.29.0 to 0.30.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aquasecurity/trivy-action/releases">aquasecurity/trivy-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.30.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: Update default trivy version in README by <a
href="https://github.com/derrix060"><code>@​derrix060</code></a> in <a
href="https://redirect.github.com/aquasecurity/trivy-action/pull/444">aquasecurity/trivy-action#444</a></li>
<li>fix: typo in description of an input for action.yaml by <a
href="https://github.com/yutatokoi"><code>@​yutatokoi</code></a> in <a
href="https://redirect.github.com/aquasecurity/trivy-action/pull/452">aquasecurity/trivy-action#452</a></li>
<li>Improve README/SBOM by <a
href="https://github.com/AB-xdev"><code>@​AB-xdev</code></a> in <a
href="https://redirect.github.com/aquasecurity/trivy-action/pull/439">aquasecurity/trivy-action#439</a></li>
<li>chore: bump trivy to v0.60.0 by <a
href="https://github.com/nikpivkin"><code>@​nikpivkin</code></a> in <a
href="https://redirect.github.com/aquasecurity/trivy-action/pull/453">aquasecurity/trivy-action#453</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/derrix060"><code>@​derrix060</code></a>
made their first contribution in <a
href="https://redirect.github.com/aquasecurity/trivy-action/pull/444">aquasecurity/trivy-action#444</a></li>
<li><a href="https://github.com/yutatokoi"><code>@​yutatokoi</code></a>
made their first contribution in <a
href="https://redirect.github.com/aquasecurity/trivy-action/pull/452">aquasecurity/trivy-action#452</a></li>
<li><a href="https://github.com/AB-xdev"><code>@​AB-xdev</code></a> made
their first contribution in <a
href="https://redirect.github.com/aquasecurity/trivy-action/pull/439">aquasecurity/trivy-action#439</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/aquasecurity/trivy-action/compare/0.29.0...0.30.0">https://github.com/aquasecurity/trivy-action/compare/0.29.0...0.30.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/aquasecurity/trivy-action/commit/6c175e9c4083a92bbca2f9724c8a5e33bc2d97a5"><code>6c175e9</code></a>
chore: bump trivy to v0.60.0 (<a
href="https://redirect.github.com/aquasecurity/trivy-action/issues/453">#453</a>)</li>
<li><a
href="https://github.com/aquasecurity/trivy-action/commit/53e8848d3e517db48b0e70ae4f648a12ae04fe02"><code>53e8848</code></a>
Improve README/SBOM (<a
href="https://redirect.github.com/aquasecurity/trivy-action/issues/439">#439</a>)</li>
<li><a
href="https://github.com/aquasecurity/trivy-action/commit/ef1b561207528e89045580cdc5a02032d8a544df"><code>ef1b561</code></a>
fix: typo in description of an input for action.yaml (<a
href="https://redirect.github.com/aquasecurity/trivy-action/issues/452">#452</a>)</li>
<li><a
href="https://github.com/aquasecurity/trivy-action/commit/a11da62073708815958ea6d84f5650c78a3ef85b"><code>a11da62</code></a>
fix: Update default trivy version in README (<a
href="https://redirect.github.com/aquasecurity/trivy-action/issues/444">#444</a>)</li>
<li>See full diff in <a
href="https://github.com/aquasecurity/trivy-action/compare/18f2510ee396bbf400402947b394f2dd8c87dbb0...6c175e9c4083a92bbca2f9724c8a5e33bc2d97a5">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-17 11:56:03 +00:00
Mathias Fredriksson c429e0d5f3 test(cryptorand): re-enable number error tests (#16956)
Realized it was only the `StringCharset` test that lead to panic, the
number tests bypass it by reading via the `binary` package.
2025-03-17 10:39:48 +00:00
Mathias Fredriksson e6983d8399 test(cryptorand): disable error tests on Go 1.24 (#16955)
Testing `rand.Reader.Read` for errors will panic (not recoverable) in Go
1.24 and later.
2025-03-17 12:15:52 +02:00
Mathias Fredriksson df92df4565 fix(agent): filter out GOTRACEBACK=none (#16924)
With the switch to Go 1.24.1, our dogfood workspaces started setting
`GOTRACEBACK=none` in the environment, resulting in missing stacktraces
for users.

This is due to the capability changes we do when
`USE_CAP_NET_ADMIN=true`.

https://github.com/coder/coder/blob/564b387262e5b768c503e5317242d9ab576395d6/provisionersdk/scripts/bootstrap_linux.sh#L60-L76

This most likely triggers a change in securitybits which sets
`_AT_SECURE` for the process.

https://github.com/golang/go/blob/a1ddbdd3ef8b739aab53f20d6ed0a61c3474cf12/src/runtime/os_linux.go#L297-L327

Which in turn triggers secure mode:

https://github.com/golang/go/blob/a1ddbdd3ef8b739aab53f20d6ed0a61c3474cf12/src/runtime/security_unix.go

This should not affect workspaces as template authors can still set the
environment on the agent resource.

See https://pkg.go.dev/runtime#hdr-Security
2025-03-17 11:10:14 +02:00
ケイラ f01ee963b2 fix: fix audit log search (#16944) 2025-03-14 18:05:19 -06:00
Edward Angert ffd336b9ad docs: adjust order of options in external-auth (#16943)
from @NickSquangler 

> ($customer) noticed when setting up external auth with Gitlab that the
command listed in the docs is in the incorrect order, as `coder
external-auth <USER_DEFINED_ID> access-token` should be `coder
external-auth access-token <USER_DEFINED_ID>`


[preview](https://coder.com/docs/@external-auth-access-token/admin/external-auth#workspace-cli)

<details><summary>coder external-auth access-token --help</summary>

```shell
coder external-auth access-token --help
coder v2.20.0+03b5012

USAGE:
  coder external-auth access-token [flags] <provider>

  Print auth for an external provider

  Print an access-token for an external auth provider. The access-token will be validated and sent
  to stdout with exit code 0. If a valid access-token cannot be obtained, the URL to authenticate
  will be sent to stdout with exit code 1
    - Ensure that the user is authenticated with GitHub before cloning.:

        $ #!/usr/bin/env sh

  OUTPUT=$(coder external-auth access-token github)
  if [ $? -eq 0 ]; then
    echo "Authenticated with GitHub"
  else
    echo "Please authenticate with GitHub:"
    echo $OUTPUT
  fi


    - Obtain an extra property of an access token for additional metadata.:

        $ coder external-auth access-token slack --extra "authed_user.id"


OPTIONS:
      --extra string
          Extract a field from the "extra" properties of the OAuth token.

———
Run `coder --help` for a list of global options.
```

</details>

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-14 17:17:34 -04:00
Edward Angert a2131a7616 docs: add cgroup memory troubleshooting to install doc (#16920)
originally thought this fit under [Unofficial Install
Methods](https://coder.com/docs/install/other), but we don't talk about
Raspberry Pi anywhere, so ~the general Install doc might be a better
fit~ moved to admin>templates>troubleshooting


[preview](https://coder.com/docs/@3-cgroup-mem/admin/templates/troubleshooting#coder-on-raspberry-pi-os)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
2025-03-14 19:58:01 +00:00
brettkolodny 1ec39f4c55 feat: add pagination to the organizaton members table (#16870)
Closes
[coder/internal#344](https://github.com/coder/internal/issues/344)
2025-03-14 14:27:55 -04:00
Eric Paulsen 7ba4df1bc4 docs: fix offline dockerfile bug (#16923)
bug caused via the `apk del terraform` line in our Dockerfile, which
does not yet exist in the Alpine Linux OS.

removing this line (18) results in successful builds.
2025-03-14 12:11:14 -04:00
ケイラ 673294deab chore: add e2e test for updating theme (#16897) 2025-03-14 09:16:47 -06:00
Bruno Quaresma 564b387262 feat: add provisioner jobs into the UI (#16867)
- Add provisioner jobs back, but as a sub page of the organization
settings
- Add missing storybook tests to the components

Related to https://github.com/coder/coder/issues/15192.
2025-03-14 08:22:00 -03:00
Edward Angert cf7d143e43 docs: use consistent examples in prometheus doc and add namespaceSelector spec (#16918)
closes: #15385 

- use consistent `prom-http` port (@johnstcn looks like this was
changed/added in #12214 - do we prefer `prom-http` over
`prometheus-http` or is it more important that they align?)
- add `namespaceSelector:` per @francisco-mata (thanks! - sorry it took
so long to get this in)

   from issue:

> For some reason our target was not appearing on our prometheus
targets, we had to add a namespaceSelector key on the Service Monitor to
successfully appear

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-13 22:09:26 -04:00
Jaayden Halko 0ea804ccea chore: migrate settings page tables from mui to shadcn (#16896)
Custom Roles
<img width="795" alt="Screenshot 2025-03-12 at 21 04 53"
src="https://github.com/user-attachments/assets/d478e80d-6d11-496c-a37f-87a73a5587b7"
/>

Group Page
<img width="804" alt="Screenshot 2025-03-12 at 21 04 12"
src="https://github.com/user-attachments/assets/eec9749a-7a34-42ca-97a8-c2a624f766bb"
/>

Groups Page
<img width="802" alt="Screenshot 2025-03-12 at 21 04 06"
src="https://github.com/user-attachments/assets/7b88f6ab-9364-4e15-b969-8e422b24085c"
/>

Users Page
<img width="820" alt="Screenshot 2025-03-12 at 21 03 58"
src="https://github.com/user-attachments/assets/195dea6e-c57f-4155-8d71-3adc3a6202bc"
/>
2025-03-13 17:34:00 -04:00
Mathias Fredriksson a1f5468db2 chore(provisioner/terraform): minimize testdata diff (#16908)
It was hard to deduce whether or not changes in our terraform testdata
are relevant or not, so we now have a rudimentary filter for randomly
generated values that aren't relevant for the testdata.
2025-03-13 20:12:59 +02:00
Thomas Kosiewski 7171d52279 fix: replace both colons and slashes in SBOM filename for Docker image (#16915)
This PR fixes the SBOM filename generation in the Docker build script to
properly handle image tags that contain slashes. The current
implementation only replaces colons with underscores, but fails when
image tags include slashes (common in registry paths).

The fix updates the string replacement to handle both colons and slashes
in the image tag when generating the SBOM filename.

Change-Id: Ifd7bad6d165393e11202e5bf070a4cb26eaa6a6a
Signed-off-by: Thomas Kosiewski <tk@coder.com>

Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-03-13 23:01:03 +05:00
Thomas Kosiewski 389af22dac chore: replace colons in SBOM filename for Docker image attestation (#16914)
This PR fixes an issue in the Docker build script where the SBOM file path used the image tag directly, which could contain colons. Since colons are not valid characters in filenames on many filesystems, this replaces colons with underscores in the output filename.

Change-Id: I887f4fc255d9bfa19b6c5d23ad0a5db7352aa2af
Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-03-13 18:20:43 +01:00
M Atif Ali 4987de654e chore: enable SBOM attestations for docker images (#16894)
- Enable SBOM and provenance attestations in Docker builds
- Installs `cosign` and `syft` in dogfood image
- Adds [github
attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds)

Signed-off-by: Thomas Kosiewski <tk@coder.com>

---------

Signed-off-by: Thomas Kosiewski <tk@coder.com>
Co-authored-by: Thomas Kosiewski <tk@coder.com>
2025-03-13 21:45:11 +05:00
Marcin Tojek 30179aeaac fix: apply autofocus to workspace button search (#16905)
Fixes: https://github.com/coder/coder/issues/14816
2025-03-13 13:31:18 +00:00
Ethan 4994ba1e60 docs: remove broken gfm alert (#16902)
It looks like GFM does not respect the `![]` alert syntax (and any other
alert type) when it's enclosed within a div. This is true for both the
coder.com GFM renderer, and GitHub's (though I assume they're the same
internally).

When the section is surrounded by a `<div class="tabs">`:

![image](https://github.com/user-attachments/assets/0f7d4029-a0a5-4d38-a489-f3b893c68dd8)

When it's not:

![image](https://github.com/user-attachments/assets/765d3629-0108-43cc-8047-972dfd806c7d)

In our case, we really want the tabs, and the alert block is less
important, so we'll downgrade it to a regular quote.

cc @aqandrew for visibility, in case you're aware of a workaround.
2025-03-13 16:13:02 +11:00
Ethan f899832c02 docs: add warning for multiple Coder Desktop mac installations (#16888)
I realised we should advise against installing multiple copies, as I'm sure someone will try and get confused by Apple's obtuse error messaging.

Tailscale also has a similar warning: https://pkgs.tailscale.com/stable/#macos
2025-03-13 14:45:37 +11:00
ケイラ f6382fde22 chore: update docker starter template jetbrains_ides option to match module default (#16898)
Taken from
https://github.com/coder/modules/blob/fd5dd375f7f8740226e798fc60a4a5d271b294d4/jetbrains-gateway/main.tf#L134

The order got shuffled a little, but the main difference is that the new
list includes RustRover, which is nice. :)
2025-03-12 17:12:30 -06:00
Bruno Quaresma f2cd046b2b chore: add notification UI components (#16818)
Related to https://github.com/coder/internal/issues/336

This PR adds the base components for the Notifications UI below (you can
click on the image to open the related Figma design) based on the
response structure defined on this [notion
doc](https://www.notion.so/coderhq/Coder-Inbox-Endpoints-1a1d579be592809eb921f13baf18f783).

[![new notifications including
hover](https://github.com/user-attachments/assets/885fb055-544e-4d9e-b5bf-be986e8b9fc0)](https://www.figma.com/design/5kRpzK8Qr1k38nNz7H0HSh/Inbox-notifications?node-id=2-1098&m=dev)

**What is not included**
- Support for infinite scrolling (pending on BE definition)

**How to test the components?**
- The only way to test the components is to use Chromatic or downloading
the branch and running Storybook locally.
2025-03-12 14:36:33 -03:00
Bruno Quaresma 78df7869d5 refactor: name null users in audit logs (#16890)
A few audit logs can have the user as null which means the user is not
authenticated when executing the action. To make it more explicit we
named than as "Unauthenticated user" in the log description instead of
"undefined user".
2025-03-12 11:36:38 -03:00
Thomas Kosiewski 5285c12b9e chore: update terraform to 1.11.1 in nix image (#16880)
Followup PR to #16781, update the terraform version in our Nix devshell.

Additionally: 

1. Switches from DeterminateSystems/nix-installer-action to nixbuild/nix-quick-install-action -- quicker installer, reduces actions time from ~60 seconds to ~1 seconds.
2. Adds nix-community/cache-nix-action for better caching with garbage collection -- avoids unnecessary rebuilding on subsequent runs, reduces nix image build time from ~6 minutes to <4 minutes.
3. Adds nixpkgs-unstable input to use Terraform 1.11.1

Change-Id: I05d6dfd3f3cf1af48cf8a2d9e61b396bcd2b7191
Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-03-11 16:23:33 +01:00
Cian Johnston 09dd69a7e8 chore(dogfood): include multiple templates under dogfood/ (#16846)
* Renames `dogfood/contents` to `dogfood/coder`.
* Moves `coder-envbuilder` to `dogfood/coder-envbuilder`.
* Updates `dogfood/main.tf` to push `coder-envbuilder` template.
* Replaces hard-coded organization IDs with
`data.coderd_organization.default.id`.
2025-03-11 13:17:40 +00:00
Thomas Kosiewski 9ded2cc7ec fix(flake.nix): synchronize playwright version in nix and package.json (#16715)
Ensure that the version of Playwright installed with the Nix flake is
equal to the one specified in `site/package.json.` -- This assertion
ensures that `pnpm playwright:install` will not attempt to download
newer browser versions not present in the Nix image, fixing the startup
script and reducing the startup time, as `pnpm playwright:install` will
not download or install anything.

We also pre-install the required Playwright web browsers in the dogfood
Dockerfile. This change prevents us from redownloading system
dependencies and Google Chrome each time a workspace starts.

Change-Id: I8cc78e842f7d0b1d2a90a4517a186a03636c5559
Signed-off-by: Thomas Kosiewski <tk@coder.com>

Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-03-11 13:49:03 +01:00
Mathias Fredriksson 3005cb4594 feat(agent): set additional login vars, LOGNAME and SHELL (#16874)
This change stes additional env vars. This is useful for programs that
assume their presence (for instance, Zed remote relies on SHELL).

See `man login`.
2025-03-11 10:18:57 +00:00
Jaayden Halko 86b61ef1d8 fix: use correct permissions for CRUD of custom roles (#16854)
resolves coder/internal#428

The goal of the PR is to start using updateOrgRoles and deleteOrgRoles
permissions to gate custom roles functionality

```
		updateOrgRoles: {
			object: {
				resource_type: "assign_org_role",
				organization_id: organizationId,
			},
			action: "update",
		},
		deleteOrgRoles: {
			object: {
				resource_type: "assign_org_role",
				organization_id: organizationId,
			},
			action: "delete",
		}
```
2025-03-10 18:43:09 -04:00
Edward Angert 101b62dc3e docs: convert alerts to use GitHub Flavored Markdown (GFM) (#16850)
followup to #16761 

thanks @lucasmelin !

+ thanks: @ethanndickson @Parkreiner @matifali @aqandrew 

- [x] update snippet
- [x] find/replace
- [x] spot-check


[preview](https://coder.com/docs/@16761-gfm-callouts/admin/templates/managing-templates/schedule)
(and others)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
2025-03-10 16:58:20 -04:00
M Atif Ali e817713dc0 revert: "chore: enable SBOM attestation for image builds" (#16868)
Reverts coder/coder#16852

The CI failed to create the multi-arch manifest.

https://github.com/coder/coder/actions/runs/13773079355/job/38516182819#step:18:341

I personally think we should move to a [multi-arch
Dockerfile](https://docs.docker.com/build/building/multi-platform/#cross-compilation)
instead of creating the manifest manually.
2025-03-10 19:55:03 +00:00
M Atif Ali 05ebece03a chore: enable SBOM attestation for image builds (#16852)
- Added SBOM (Software Bill of Materials) generation during Docker build
to enhance traceability. Refer to Docker documentation on SBOM:
https://docs.docker.com/build/metadata/attestations/sbom/
- Updated Docker build scripts to use BuildKit for provenance and SBOM
support: https://docs.docker.com/build/metadata/attestations/
- Configured Docker daemon in dogfood image to support the Containerd
snapshotter feature to improve performance:
https://docs.docker.com/engine/storage/containerd/

> [!Important]
> We also need to enable `containerd` on depot runners.
> <img width="587" alt="image"
src="https://github.com/user-attachments/assets/1d7f87c7-fdcc-462a-babe-87ac6486ad09"
/>



## Testing

- Tested locally with ` docker buildx build --sbom=true --output
type=local,dest=out -f Dockerfile .` to verify that an SBOM file is
generated.
- Tested in
[CI](https://github.com/coder/coder/actions/runs/13731162662/job/38408790980?pr=16852#step:17:1)
to ensure the image builds without any errors.


Also closes coder/internal#88
2025-03-11 00:24:14 +05:00
brettkolodny 8c0350e20c feat: add a paginated organization members endpoint (#16835)
Closes
[coder/internal#460](https://github.com/coder/internal/issues/460)
2025-03-10 14:42:07 -04:00
Kira Pilot 191b0efb80 fix: select default org in template form if only one exists (#16639)
resolves #16849 https://github.com/coder/internal/issues/147
![Screenshot 2025-02-19 at 9 06 16
PM](https://github.com/user-attachments/assets/2973d81d-7a74-4c82-aa6b-16d4a41eeb9a)

---------

Co-authored-by: ケイラ <mckayla@hey.com>
2025-03-10 11:56:08 -04:00
Marcin Tojek 4b1da9b896 feat(cli): preserve table column order (#16843)
Fixes: https://github.com/coder/coder/issues/16055
2025-03-10 12:28:06 +00:00
Marcin Tojek 075e5f4f6e test: skip tests affected by daylight savings issues (#16857)
Related: https://github.com/coder/internal/issues/464

This will unblock the CI pipeline.
2025-03-10 13:10:34 +01:00
dependabot[bot] 1a544f0b07 chore: bump axios from 1.7.9 to 1.8.2 in /site (#16863)
Bumps [axios](https://github.com/axios/axios) from 1.7.9 to 1.8.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/releases">axios's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.8.2</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>http-adapter:</strong> add allowAbsoluteUrls to path
building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)
(<a
href="https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f">fb8eec2</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/lexcorp16"
title="+1/-1 ([#6810](https://github.com/axios/axios/issues/6810)
)">Fasoro-Joseph Alexander</a></li>
</ul>
<h2>Release v1.8.1</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>utils:</strong> move <code>generateString</code> to platform
utils to avoid importing crypto module into client builds; (<a
href="https://redirect.github.com/axios/axios/issues/6789">#6789</a>)
(<a
href="https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec">36a5a62</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+51/-47
([#6789](https://github.com/axios/axios/issues/6789) )">Dmitriy
Mozgovoy</a></li>
</ul>
<h2>Release v1.8.0</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>examples:</strong> application crashed when navigating
examples in browser (<a
href="https://redirect.github.com/axios/axios/issues/5938">#5938</a>)
(<a
href="https://github.com/axios/axios/commit/1260ded634ec101dd5ed05d3b70f8e8f899dba6c">1260ded</a>)</li>
<li>missing word in SUPPORT_QUESTION.yml (<a
href="https://redirect.github.com/axios/axios/issues/6757">#6757</a>)
(<a
href="https://github.com/axios/axios/commit/1f890b13f2c25a016f3c84ae78efb769f244133e">1f890b1</a>)</li>
<li><strong>utils:</strong> replace getRandomValues with crypto module
(<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)
(<a
href="https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c">23a25af</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)
(<a
href="https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3">32c7bcc</a>)</li>
</ul>
<h3>Reverts</h3>
<ul>
<li>Revert &quot;chore: expose fromDataToStream to be consumable (<a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a>)&quot;
(<a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a>)
(<a
href="https://github.com/axios/axios/commit/1317261125e9c419fe9f126867f64d28f9c1efda">1317261</a>),
closes <a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a> <a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a></li>
</ul>
<h3>BREAKING CHANGES</h3>
<ul>
<li>
<p>code relying on the above will now combine the URLs instead of prefer
request URL</p>
</li>
<li>
<p>feat: add config option for allowing absolute URLs</p>
</li>
<li>
<p>fix: add default value for allowAbsoluteUrls in buildFullPath</p>
</li>
<li>
<p>fix: typo in flow control when setting allowAbsoluteUrls</p>
</li>
</ul>
<h3>Contributors to this release</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/axios/axios/compare/v1.8.1...v1.8.2">1.8.2</a>
(2025-03-07)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>http-adapter:</strong> add allowAbsoluteUrls to path
building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)
(<a
href="https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f">fb8eec2</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/lexcorp16"
title="+1/-1 ([#6810](https://github.com/axios/axios/issues/6810)
)">Fasoro-Joseph Alexander</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.8.0...v1.8.1">1.8.1</a>
(2025-02-26)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>utils:</strong> move <code>generateString</code> to platform
utils to avoid importing crypto module into client builds; (<a
href="https://redirect.github.com/axios/axios/issues/6789">#6789</a>)
(<a
href="https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec">36a5a62</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+51/-47
([#6789](https://github.com/axios/axios/issues/6789) )">Dmitriy
Mozgovoy</a></li>
</ul>
<h1><a
href="https://github.com/axios/axios/compare/v1.7.9...v1.8.0">1.8.0</a>
(2025-02-25)</h1>
<h3>Bug Fixes</h3>
<ul>
<li><strong>examples:</strong> application crashed when navigating
examples in browser (<a
href="https://redirect.github.com/axios/axios/issues/5938">#5938</a>)
(<a
href="https://github.com/axios/axios/commit/1260ded634ec101dd5ed05d3b70f8e8f899dba6c">1260ded</a>)</li>
<li>missing word in SUPPORT_QUESTION.yml (<a
href="https://redirect.github.com/axios/axios/issues/6757">#6757</a>)
(<a
href="https://github.com/axios/axios/commit/1f890b13f2c25a016f3c84ae78efb769f244133e">1f890b1</a>)</li>
<li><strong>utils:</strong> replace getRandomValues with crypto module
(<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)
(<a
href="https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c">23a25af</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)
(<a
href="https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3">32c7bcc</a>)</li>
</ul>
<h3>Reverts</h3>
<ul>
<li>Revert &quot;chore: expose fromDataToStream to be consumable (<a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a>)&quot;
(<a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a>)
(<a
href="https://github.com/axios/axios/commit/1317261125e9c419fe9f126867f64d28f9c1efda">1317261</a>),
closes <a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a> <a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a></li>
</ul>
<h3>BREAKING CHANGES</h3>
<ul>
<li>
<p>code relying on the above will now combine the URLs instead of prefer
request URL</p>
</li>
<li>
<p>feat: add config option for allowing absolute URLs</p>
</li>
<li>
<p>fix: add default value for allowAbsoluteUrls in buildFullPath</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/axios/axios/commit/a9f7689b0c4b6d68c7f587c3aa376860da509d94"><code>a9f7689</code></a>
chore(release): v1.8.2 (<a
href="https://redirect.github.com/axios/axios/issues/6812">#6812</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f"><code>fb8eec2</code></a>
fix(http-adapter): add allowAbsoluteUrls to path building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/98120457559e573024862e2925d56295a965ad7e"><code>9812045</code></a>
chore(sponsor): update sponsor block (<a
href="https://redirect.github.com/axios/axios/issues/6804">#6804</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/72acf759373ef4e211d5299818d19e50e08c02f8"><code>72acf75</code></a>
chore(sponsor): update sponsor block (<a
href="https://redirect.github.com/axios/axios/issues/6794">#6794</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/2e64afdff5c41e38284a6fb8312f2745072513a1"><code>2e64afd</code></a>
chore(release): v1.8.1 (<a
href="https://redirect.github.com/axios/axios/issues/6800">#6800</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec"><code>36a5a62</code></a>
fix(utils): move <code>generateString</code> to platform utils to avoid
importing crypto...</li>
<li><a
href="https://github.com/axios/axios/commit/cceb7b1e154fbf294135c93d3f91921643bbe49f"><code>cceb7b1</code></a>
chore(release): v1.8.0 (<a
href="https://redirect.github.com/axios/axios/issues/6795">#6795</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c"><code>23a25af</code></a>
fix(utils): replace getRandomValues with crypto module (<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3"><code>32c7bcc</code></a>
feat: Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)</li>
<li><a
href="https://github.com/axios/axios/commit/4a3e26cf65bb040b7eb4577d5fd62199b0f3d017"><code>4a3e26c</code></a>
chore(config): adjust rollup config to preserve license header to
minified Ja...</li>
<li>Additional commits viewable in <a
href="https://github.com/axios/axios/compare/v1.7.9...v1.8.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=axios&package-manager=npm_and_yarn&previous-version=1.7.9&new-version=1.8.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/coder/coder/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-10 12:10:10 +00:00
dependabot[bot] f6e821204d ci: bump github/codeql-action from 3.28.10 to 3.28.11 in the github-actions group (#16862)
Bumps the github-actions group with 1 update:
[github/codeql-action](https://github.com/github/codeql-action).

Updates `github/codeql-action` from 3.28.10 to 3.28.11
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.28.11</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v3.28.11/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>3.28.11 - 07 Mar 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.6. <a
href="https://redirect.github.com/github/codeql-action/pull/2793">#2793</a></li>
</ul>
<h2>3.28.10 - 21 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.5. <a
href="https://redirect.github.com/github/codeql-action/pull/2772">#2772</a></li>
<li>Address an issue where the CodeQL Bundle would occasionally fail to
decompress on macOS. <a
href="https://redirect.github.com/github/codeql-action/pull/2768">#2768</a></li>
</ul>
<h2>3.28.9 - 07 Feb 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.4. <a
href="https://redirect.github.com/github/codeql-action/pull/2753">#2753</a></li>
</ul>
<h2>3.28.8 - 29 Jan 2025</h2>
<ul>
<li>Enable support for Kotlin 2.1.10 when running with CodeQL CLI
v2.20.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2744">#2744</a></li>
</ul>
<h2>3.28.7 - 29 Jan 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.6 - 27 Jan 2025</h2>
<ul>
<li>Re-enable debug artifact upload for CLI versions 2.20.3 or greater.
<a
href="https://redirect.github.com/github/codeql-action/pull/2726">#2726</a></li>
</ul>
<h2>3.28.5 - 24 Jan 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.3. <a
href="https://redirect.github.com/github/codeql-action/pull/2717">#2717</a></li>
</ul>
<h2>3.28.4 - 23 Jan 2025</h2>
<p>No user facing changes.</p>
<h2>3.28.3 - 22 Jan 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.20.2. <a
href="https://redirect.github.com/github/codeql-action/pull/2707">#2707</a></li>
<li>Fix an issue downloading the CodeQL Bundle from a GitHub Enterprise
Server instance which occurred when the CodeQL Bundle had been synced to
the instance using the <a
href="https://github.com/github/codeql-action-sync-tool">CodeQL Action
sync tool</a> and the Actions runner did not have Zstandard installed.
<a
href="https://redirect.github.com/github/codeql-action/pull/2710">#2710</a></li>
<li>Uploading debug artifacts for CodeQL analysis is temporarily
disabled. <a
href="https://redirect.github.com/github/codeql-action/pull/2712">#2712</a></li>
</ul>
<h2>3.28.2 - 21 Jan 2025</h2>
<p>No user facing changes.</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/6bb031afdd8eb862ea3fc1848194185e076637e5"><code>6bb031a</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2798">#2798</a>
from github/update-v3.28.11-56b25d5d5</li>
<li><a
href="https://github.com/github/codeql-action/commit/6bca7dd940f38115b5e3696bd79bbb020563bb1f"><code>6bca7dd</code></a>
Update changelog for v3.28.11</li>
<li><a
href="https://github.com/github/codeql-action/commit/56b25d5d5251df651f82070735778784aa383094"><code>56b25d5</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2793">#2793</a>
from github/update-bundle/codeql-bundle-v2.20.6</li>
<li><a
href="https://github.com/github/codeql-action/commit/256aa1658211f7bf42a0ee5b18a106fe81baa524"><code>256aa16</code></a>
Merge branch 'main' into update-bundle/codeql-bundle-v2.20.6</li>
<li><a
href="https://github.com/github/codeql-action/commit/911d845ab60270de25813c5a148ec9501e857340"><code>911d845</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2796">#2796</a>
from github/nickfyson/adjust-rate-error-string</li>
<li><a
href="https://github.com/github/codeql-action/commit/7b7ed635033f63c6f84ab377f726dc0b933bd593"><code>7b7ed63</code></a>
adjust string for handling rate limit error</li>
<li><a
href="https://github.com/github/codeql-action/commit/608ccd6cd915d2c43d3059c3da518f36f07a56b0"><code>608ccd6</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/2794">#2794</a>
from github/update-supported-enterprise-server-versions</li>
<li><a
href="https://github.com/github/codeql-action/commit/35d04d3627f40144b1b19daa99f2449297367ec9"><code>35d04d3</code></a>
Update supported GitHub Enterprise Server versions</li>
<li><a
href="https://github.com/github/codeql-action/commit/ec3b22164b6b09c9b3d63ff4e9d41084895602b0"><code>ec3b221</code></a>
Update supported GitHub Enterprise Server versions</li>
<li><a
href="https://github.com/github/codeql-action/commit/8dc01f6342a3f934d1a339917531a4d8beda41bc"><code>8dc01f6</code></a>
Add changelog note</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d...6bb031afdd8eb862ea3fc1848194185e076637e5">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.28.10&new-version=3.28.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-10 11:58:44 +00:00
Ben Potter 1a50d33789 fix: remove <title> from bug template (#16856) 2025-03-09 21:00:22 +00:00
ケイラ ec11f11ac5 fix: improve permissions checks in organization settings (#16849) 2025-03-07 14:45:29 -07:00
ケイラ 092c129de0 chore: perform several small frontend permissions refactors (#16735) 2025-03-07 10:33:09 -07:00
M Atif Ali 54745b1d3f chore(dogfood): update Zed URI to use Coder Desktop provided DNS entries (#16847) 2025-03-07 22:27:49 +05:00
ケイラ 26832cba93 chore: remove old CreateTemplateButton component (#16836) 2025-03-07 10:22:11 -07:00
Cian Johnston 61246bc48e fix(agent/agentcontainers): correct definition of remoteEnv (#16845)
`devcontainer.metadata` is apparently an array, not an object. Missed
this first time round!

```
    error= get container env info:
               github.com/coder/coder/v2/agent/reconnectingpty.(*Server).handleConn
                   /home/runner/work/coder/coder/agent/reconnectingpty/server.go:193
             - read devcontainer remoteEnv:
               github.com/coder/coder/v2/agent/agentcontainers.EnvInfo
                   /home/runner/work/coder/coder/agent/agentcontainers/containers_dockercli.go:119
             - unmarshal devcontainer.metadata:
               github.com/coder/coder/v2/agent/agentcontainers.devcontainerEnv
                   /home/runner/work/coder/coder/agent/agentcontainers/containers_dockercli.go:189
             - json: cannot unmarshal array into Go value of type struct { RemoteEnv map[string]string "json:\"remoteEnv\"" }
```
2025-03-07 15:59:37 +00:00
ケイラ 32c36d5336 feat: allow selecting the initial organization for new users (#16829) 2025-03-07 08:42:10 -07:00
Lucas Melin db064ed0f8 docs: fix formatting of note callouts (#16761)
Fixes the formatting of several note callouts. Previously, these would render incorrectly both on GitHub and on the documentation site.
2025-03-07 10:35:14 -05:00
Ethan 17f8e93d0c chore: add agent endpoint for querying file system (#16736)
Closes https://github.com/coder/internal/issues/382
2025-03-07 15:33:50 +11:00
ケイラ eddccbca5c fix: hide deleted users from org members query (#16830) 2025-03-06 11:50:08 -07:00
M Atif Ali 9bed9a226a docs: update versions in offline installation docs (#16808)
[preview](https://coder.com/docs/@matifali-patch-1/install/offline)

---------

Co-authored-by: Edward Angert <EdwardAngert@users.noreply.github.com>
2025-03-06 21:35:41 +05:00
Edward Angert f5aac64119 docs: add beta label to workspace presets (#16826)
thanks @ssncoder!


[preview](https://coder.com/docs/@workspace-presets-beta/admin/templates/extending-templates/parameters#workspace-presets)

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-06 09:09:15 -05:00
Danny Kopping b16275b7cd chore: fix regex bug in migration number fixer (#16822)
This fixes a slight regex bug on Bash 5, where `[:/]` would only match
`:` but not both `:/`.

```bash
$ git remote -v | grep "github.com[:/]coder/coder.*(fetch)" | cut -f1

$ git remote -v | grep "github.com[:/]*coder/coder.*(fetch)" | cut -f1
origin
```

The former will actually cause the whole script to bork because of
`pipefail`, since `grep` exits 1.

Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2025-03-06 12:21:14 +02:00
Vincent Vielle 0c27f04bc7 fix(coderd): fix migration number overlapping (#16819)
Due to the [merge of this PR](https://github.com/coder/coder/pull/16764)
- two migration are overlapping in term of numbers - should increase
migration number of notifications.
2025-03-05 23:13:42 +01:00
Vincent Vielle 522181fead feat(coderd): add new dispatch logic for coder inbox (#16764)
This PR is [resolving the dispatch part of Coder
Inbocx](https://github.com/coder/internal/issues/403).

Since the DB layer has been merged - we now want to insert notifications
into Coder Inbox in parallel of the other delivery target.

To do so, we push two messages instead of one using the `Enqueue`
method.
2025-03-05 22:43:18 +01:00
M Atif Ali 32450a2f77 docs: update docs for 2.20 release (#16817)
Updates Helm chart versions and updating support statuses for various
versions.
2025-03-06 01:54:26 +05:00
ケイラ deb95f948a chore: remove unused code (#16815) 2025-03-05 13:53:21 -07:00
ケイラ 9041646b81 chore: add "user_configs" db table (#16564) 2025-03-05 10:46:03 -07:00
Mathias Fredriksson cc946f199d test(cli): improve TestServer/SpammyLogs line count (#16814) 2025-03-05 17:04:35 +02:00
Marcin Tojek 77479cdd51 fix: hide "last seen" when user is suspended (#16813)
Fixes: https://github.com/coder/coder/issues/14887
2025-03-05 14:02:12 +01:00
Edward Angert 0913594bfc docs: document workspace presets feature (#16612)
closes #16475 

relates to #16304 

- [x] reword opening sentence to clarify where this is done
   - I think this is set because it's under parameters now
- [x] list of configurable settings
   - same as above
- [x] (optional) screenshot



[preview](https://coder.com/docs/@16475-workspace-presets/admin/templates/extending-templates/parameters#workspace-presets)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-05 14:43:20 +05:00
Edward Angert 9251e0d642 docs: add oom/ood to notifications (#16582)
- [x] add section or to another section: where the notifications show
up/how to access

previews:
- [Notifications - Configure OOM/OOD
notifications](https://coder.com/docs/@16581-oom-ood-notif/admin/monitoring/notifications#configure-oomood-notifications)
- [Resource
monitoring](https://coder.com/docs/@16581-oom-ood-notif/admin/templates/extending-templates/resource-monitoring)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-03-05 14:43:08 +05:00
ケイラ edf28895c7 feat: check for .ps1 dotfiles scripts on windows (#16785) 2025-03-04 15:37:29 -07:00
Jon Ayers 10f1e0b39a chore: update terraform to 1.11.0 (#16781) 2025-03-04 14:28:41 -05:00
Bruno Quaresma 861c4b140b feat: add devcontainer in the UI (#16800)
![image](https://github.com/user-attachments/assets/361f9e69-dec8-47c8-b075-7c13ce84c7e8)

Related to https://github.com/coder/coder/issues/16422

---------

Co-authored-by: Cian Johnston <cian@coder.com>
2025-03-04 14:29:02 -03:00
Edward Angert 73057eb7bd docs: add Coder Desktop early preview documentation (#16544)
closes #16540 
closes https://github.com/coder/coder-desktop-macos/issues/75

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: M Atif Ali <atif@coder.com>
Co-authored-by: Ethan Dickson <ethan@coder.com>
Co-authored-by: Dean Sheather <dean@deansheather.com>
2025-03-04 22:26:59 +05:00
Mathias Fredriksson 6dd71b1055 fix(coderd/cryptokeys): relock mutex to avoid double unlock (#16802) 2025-03-04 17:10:12 +00:00
dependabot[bot] f21fcbd001 ci: bump the github-actions group across 1 directory with 5 updates (#16803)
Bumps the github-actions group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/cache](https://github.com/actions/cache) | `4.2.1` | `4.2.2`
|
| [crate-ci/typos](https://github.com/crate-ci/typos) | `1.29.9` |
`1.29.10` |
|
[actions/download-artifact](https://github.com/actions/download-artifact)
| `4.1.8` | `4.1.9` |
|
[google-github-actions/get-gke-credentials](https://github.com/google-github-actions/get-gke-credentials)
| `2.3.1` | `2.3.3` |
|
[docker/setup-buildx-action](https://github.com/docker/setup-buildx-action)
| `3.9.0` | `3.10.0` |


Updates `actions/cache` from 4.2.1 to 4.2.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/releases">actions/cache's
releases</a>.</em></p>
<blockquote>
<h2>v4.2.2</h2>
<h2>What's Changed</h2>
<blockquote>
<p>[!IMPORTANT]
As a reminder, there were important backend changes to release v4.2.0,
see <a href="https://github.com/actions/cache/releases/tag/v4.2.0">those
release notes</a> and <a
href="https://github.com/actions/cache/discussions/1510">the
announcement</a> for more details.</p>
</blockquote>
<ul>
<li>Bump <code>@​actions/cache</code> to v4.0.2 by <a
href="https://github.com/robherley"><code>@​robherley</code></a> in <a
href="https://redirect.github.com/actions/cache/pull/1560">actions/cache#1560</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v4.2.1...v4.2.2">https://github.com/actions/cache/compare/v4.2.1...v4.2.2</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/blob/main/RELEASES.md">actions/cache's
changelog</a>.</em></p>
<blockquote>
<h1>Releases</h1>
<h3>4.2.2</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v4.0.2</li>
</ul>
<h3>4.2.1</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v4.0.1</li>
</ul>
<h3>4.2.0</h3>
<p>TLDR; The cache backend service has been rewritten from the ground up
for improved performance and reliability. <a
href="https://github.com/actions/cache">actions/cache</a> now integrates
with the new cache service (v2) APIs.</p>
<p>The new service will gradually roll out as of <strong>February 1st,
2025</strong>. The legacy service will also be sunset on the same date.
Changes in these release are <strong>fully backward
compatible</strong>.</p>
<p><strong>We are deprecating some versions of this action</strong>. We
recommend upgrading to version <code>v4</code> or <code>v3</code> as
soon as possible before <strong>February 1st, 2025.</strong> (Upgrade
instructions below).</p>
<p>If you are using pinned SHAs, please use the SHAs of versions
<code>v4.2.0</code> or <code>v3.4.0</code></p>
<p>If you do not upgrade, all workflow runs using any of the deprecated
<a href="https://github.com/actions/cache">actions/cache</a> will
fail.</p>
<p>Upgrading to the recommended versions will not break your
workflows.</p>
<h3>4.1.2</h3>
<ul>
<li>Add GitHub Enterprise Cloud instances hostname filters to inform API
endpoint choices - <a
href="https://redirect.github.com/actions/cache/pull/1474">#1474</a></li>
<li>Security fix: Bump braces from 3.0.2 to 3.0.3 - <a
href="https://redirect.github.com/actions/cache/pull/1475">#1475</a></li>
</ul>
<h3>4.1.1</h3>
<ul>
<li>Restore original behavior of <code>cache-hit</code> output - <a
href="https://redirect.github.com/actions/cache/pull/1467">#1467</a></li>
</ul>
<h3>4.1.0</h3>
<ul>
<li>Ensure <code>cache-hit</code> output is set when a cache is missed -
<a
href="https://redirect.github.com/actions/cache/pull/1404">#1404</a></li>
<li>Deprecate <code>save-always</code> input - <a
href="https://redirect.github.com/actions/cache/pull/1452">#1452</a></li>
</ul>
<h3>4.0.2</h3>
<ul>
<li>Fixed restore <code>fail-on-cache-miss</code> not working.</li>
</ul>
<h3>4.0.1</h3>
<ul>
<li>Updated <code>isGhes</code> check</li>
</ul>
<h3>4.0.0</h3>
<ul>
<li>Updated minimum runner version support from node 12 -&gt; node
20</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/cache/commit/d4323d4df104b026a6aa633fdb11d772146be0bf"><code>d4323d4</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1560">#1560</a>
from actions/robherley/v4.2.2</li>
<li><a
href="https://github.com/actions/cache/commit/da26677639ccfb4615f1acc52d1fc3dc89152490"><code>da26677</code></a>
bump <code>@​actions/cache</code> to v4.0.2, prep for v4.2.2
release</li>
<li><a
href="https://github.com/actions/cache/commit/7921ae235bdcb376cc8f22558dc5f8ddc3c3c2f9"><code>7921ae2</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/cache/issues/1557">#1557</a>
from actions/robherley/ia-workflow-released</li>
<li><a
href="https://github.com/actions/cache/commit/393773170624981bfaa3aac1cb736e3004eac1de"><code>3937731</code></a>
Update publish-immutable-actions.yml</li>
<li>See full diff in <a
href="https://github.com/actions/cache/compare/0c907a75c2c80ebcb7f088228285e798b750cf8f...d4323d4df104b026a6aa633fdb11d772146be0bf">compare
view</a></li>
</ul>
</details>
<br />

Updates `crate-ci/typos` from 1.29.9 to 1.29.10
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/releases">crate-ci/typos's
releases</a>.</em></p>
<blockquote>
<h2>v1.29.10</h2>
<h2>[1.29.10] - 2025-02-25</h2>
<h3>Fixes</h3>
<ul>
<li>Also correct <code>contaminent</code> as
<code>contaminant</code></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/crate-ci/typos/blob/master/CHANGELOG.md">crate-ci/typos's
changelog</a>.</em></p>
<blockquote>
<h1>Change Log</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>The format is based on <a href="http://keepachangelog.com/">Keep a
Changelog</a>
and this project adheres to <a href="http://semver.org/">Semantic
Versioning</a>.</p>
<!-- raw HTML omitted -->
<h2>[Unreleased] - ReleaseDate</h2>
<h2>[1.30.1] - 2025-03-04</h2>
<h3>Features</h3>
<ul>
<li><em>(action)</em> Create <code>v1</code> tag</li>
</ul>
<h2>[1.30.0] - 2025-03-01</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1221">February
2025</a> changes</li>
</ul>
<h2>[1.29.10] - 2025-02-25</h2>
<h3>Fixes</h3>
<ul>
<li>Also correct <code>contaminent</code> as
<code>contaminant</code></li>
</ul>
<h2>[1.29.9] - 2025-02-20</h2>
<h3>Fixes</h3>
<ul>
<li><em>(action)</em> Correctly get binary for some aarch64 systems</li>
</ul>
<h2>[1.29.8] - 2025-02-19</h2>
<h3>Features</h3>
<ul>
<li>Attempt to build Linux aarch64 binaries</li>
</ul>
<h2>[1.29.7] - 2025-02-13</h2>
<h3>Fixes</h3>
<ul>
<li>Don't correct <code>implementors</code></li>
</ul>
<h2>[1.29.6] - 2025-02-13</h2>
<h3>Features</h3>
<ul>
<li>Updated the dictionary with the <a
href="https://redirect.github.com/crate-ci/typos/issues/1200">January
2025</a> changes</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/crate-ci/typos/commit/db35ee91e80fbb447f33b0e5fbddb24d2a1a884f"><code>db35ee9</code></a>
chore: Release</li>
<li><a
href="https://github.com/crate-ci/typos/commit/9f43c4dbd2d1468320524b1bf059d6032cbc5a9e"><code>9f43c4d</code></a>
docs: Update changelog</li>
<li><a
href="https://github.com/crate-ci/typos/commit/a1da2ce137a90ed418bda5bdb706e97e958f18e7"><code>a1da2ce</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1244">#1244</a>
from epage/containment</li>
<li><a
href="https://github.com/crate-ci/typos/commit/d74d5fd5ad85ea0d689c44b7d4013431b28423ac"><code>d74d5fd</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1243">#1243</a>
from epage/dict</li>
<li><a
href="https://github.com/crate-ci/typos/commit/fa6122604f999e8dafb43b92eb3da3e90136a789"><code>fa61226</code></a>
refactor(dict): Drop a dict</li>
<li><a
href="https://github.com/crate-ci/typos/commit/6276d585f79214fb7db70ff1f93dbcb404e0bc9c"><code>6276d58</code></a>
fix(dict): Correct contaminents to another spelling</li>
<li><a
href="https://github.com/crate-ci/typos/commit/07c9e1f6faffe39ca3e52afe58ae8731cc4ebcf7"><code>07c9e1f</code></a>
chore(deps): Update Rust Stable to v1.85 (<a
href="https://redirect.github.com/crate-ci/typos/issues/1241">#1241</a>)</li>
<li><a
href="https://github.com/crate-ci/typos/commit/71643b1191585cd20de3b91d9c1e73d949309530"><code>71643b1</code></a>
Merge pull request <a
href="https://redirect.github.com/crate-ci/typos/issues/1240">#1240</a>
from szepeviktor/patch-1</li>
<li><a
href="https://github.com/crate-ci/typos/commit/931a5804a4dffb6343188d152e0c08c2147b5174"><code>931a580</code></a>
Fix typo in README</li>
<li><a
href="https://github.com/crate-ci/typos/commit/c5137fd6aab66cddb011a1cb93e2553f56cafc9f"><code>c5137fd</code></a>
refactor(action): Isolate unique parts</li>
<li>See full diff in <a
href="https://github.com/crate-ci/typos/compare/212923e4ff05b7fc2294a204405eec047b807138...db35ee91e80fbb447f33b0e5fbddb24d2a1a884f">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/download-artifact` from 4.1.8 to 4.1.9
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.9</h2>
<h2>What's Changed</h2>
<ul>
<li>Add workflow file for publishing releases to immutable action
package by <a
href="https://github.com/Jcambass"><code>@​Jcambass</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/354">actions/download-artifact#354</a></li>
<li>docs: small migration fix by <a
href="https://github.com/froblesmartin"><code>@​froblesmartin</code></a>
in <a
href="https://redirect.github.com/actions/download-artifact/pull/370">actions/download-artifact#370</a></li>
<li>Update MIGRATION.md by <a
href="https://github.com/andyfeller"><code>@​andyfeller</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/372">actions/download-artifact#372</a></li>
<li>Update artifact package to 2.2.2 by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/380">actions/download-artifact#380</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Jcambass"><code>@​Jcambass</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/354">actions/download-artifact#354</a></li>
<li><a
href="https://github.com/froblesmartin"><code>@​froblesmartin</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/370">actions/download-artifact#370</a></li>
<li><a
href="https://github.com/andyfeller"><code>@​andyfeller</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/372">actions/download-artifact#372</a></li>
<li><a href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/380">actions/download-artifact#380</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v4...v4.1.9">https://github.com/actions/download-artifact/compare/v4...v4.1.9</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/download-artifact/commit/cc203385981b70ca67e1cc392babf9cc229d5806"><code>cc20338</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/380">#380</a>
from actions/yacaovsnc/release_4_1_9</li>
<li><a
href="https://github.com/actions/download-artifact/commit/1fc0fee191f40422f502da571c0f01ff460afe53"><code>1fc0fee</code></a>
Update artifact package to 2.2.2</li>
<li><a
href="https://github.com/actions/download-artifact/commit/7fba95161a0924506ed1ae69cdbae8371ee00b3f"><code>7fba951</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/372">#372</a>
from andyfeller/patch-1</li>
<li><a
href="https://github.com/actions/download-artifact/commit/f9ceb7763ba1fdfd81b2e2f93aa1f6015ff6b35d"><code>f9ceb77</code></a>
Update MIGRATION.md</li>
<li><a
href="https://github.com/actions/download-artifact/commit/533298bc57c27f112a2c04a74a04a4d43e2866fd"><code>533298b</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/370">#370</a>
from froblesmartin/patch-1</li>
<li><a
href="https://github.com/actions/download-artifact/commit/d06289e120b300840a833b25db66cb8c19f5d274"><code>d06289e</code></a>
docs: small migration fix</li>
<li><a
href="https://github.com/actions/download-artifact/commit/d0ce8fd1167ed839810201de977912a090ab10a7"><code>d0ce8fd</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/354">#354</a>
from actions/Jcambass-patch-1</li>
<li><a
href="https://github.com/actions/download-artifact/commit/1ce0d91ace59dfbf6763107ee5aa8466ebbadf48"><code>1ce0d91</code></a>
Add workflow file for publishing releases to immutable action
package</li>
<li>See full diff in <a
href="https://github.com/actions/download-artifact/compare/fa0a91b85d4f404e444e00e005971372dc801d16...cc203385981b70ca67e1cc392babf9cc229d5806">compare
view</a></li>
</ul>
</details>
<br />

Updates `google-github-actions/get-gke-credentials` from 2.3.1 to 2.3.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/google-github-actions/get-gke-credentials/releases">google-github-actions/get-gke-credentials's
releases</a>.</em></p>
<blockquote>
<h2>v2.3.3</h2>
<h2>What's Changed</h2>
<ul>
<li>Description must be less than 125 characters by <a
href="https://github.com/sethvargo"><code>@​sethvargo</code></a> in <a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/pull/331">google-github-actions/get-gke-credentials#331</a></li>
<li>Release: v2.3.3 by <a
href="https://github.com/google-github-actions-bot"><code>@​google-github-actions-bot</code></a>
in <a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/pull/332">google-github-actions/get-gke-credentials#332</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/google-github-actions/get-gke-credentials/compare/v2.3.2...v2.3.3">https://github.com/google-github-actions/get-gke-credentials/compare/v2.3.2...v2.3.3</a></p>
<h2>v2.3.2</h2>
<h2>What's Changed</h2>
<ul>
<li>security: bump jsonpath-plus from 10.2.0 to 10.3.0 in the
npm_and_yarn group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/pull/327">google-github-actions/get-gke-credentials#327</a></li>
<li>Update deps by <a
href="https://github.com/sethvargo"><code>@​sethvargo</code></a> in <a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/pull/329">google-github-actions/get-gke-credentials#329</a></li>
<li>Release: v2.3.2 by <a
href="https://github.com/google-github-actions-bot"><code>@​google-github-actions-bot</code></a>
in <a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/pull/330">google-github-actions/get-gke-credentials#330</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/google-github-actions/get-gke-credentials/compare/v2.3.1...v2.3.2">https://github.com/google-github-actions/get-gke-credentials/compare/v2.3.1...v2.3.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/google-github-actions/get-gke-credentials/commit/d0cee45012069b163a631894b98904a9e6723729"><code>d0cee45</code></a>
Release: v2.3.3 (<a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/issues/332">#332</a>)</li>
<li><a
href="https://github.com/google-github-actions/get-gke-credentials/commit/c1387e6b1efc91945c5f6150f3375ef91a6b69a0"><code>c1387e6</code></a>
Description must be less than 125 characters (<a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/issues/331">#331</a>)</li>
<li><a
href="https://github.com/google-github-actions/get-gke-credentials/commit/d08c14912d6642ca79ec62782b87462236685240"><code>d08c149</code></a>
Release: v2.3.2 (<a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/issues/330">#330</a>)</li>
<li><a
href="https://github.com/google-github-actions/get-gke-credentials/commit/5f781aae169bd8866ca79bbc10c402a1256d2ed1"><code>5f781aa</code></a>
Update deps (<a
href="https://redirect.github.com/google-github-actions/get-gke-credentials/issues/329">#329</a>)</li>
<li><a
href="https://github.com/google-github-actions/get-gke-credentials/commit/67b31da175b2546b2afc28460d0cafe927e6fd42"><code>67b31da</code></a>
security: bump jsonpath-plus from 10.2.0 to 10.3.0 in the npm_and_yarn
group ...</li>
<li>See full diff in <a
href="https://github.com/google-github-actions/get-gke-credentials/compare/7a108e64ed8546fe38316b4086e91da13f4785e1...d0cee45012069b163a631894b98904a9e6723729">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/setup-buildx-action` from 3.9.0 to 3.10.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/setup-buildx-action/releases">docker/setup-buildx-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.10.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.54.0 to 0.56.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/408">docker/setup-buildx-action#408</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.9.0...v3.10.0">https://github.com/docker/setup-buildx-action/compare/v3.9.0...v3.10.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2"><code>b5ca514</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/408">#408</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/1418a4ef330cff3d80e8707b47780be815fb20db"><code>1418a4e</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/93acf831ce48bc806b62b1e892b89fca8bf213e0"><code>93acf83</code></a>
build(deps): bump <code>@​docker/actions-toolkit</code> from 0.54.0 to
0.56.0</li>
<li>See full diff in <a
href="https://github.com/docker/setup-buildx-action/compare/f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca...b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2">compare
view</a></li>
</ul>
</details>
<br />

<details>
<summary>Most Recent Ignore Conditions Applied to This Pull
Request</summary>

| Dependency Name | Ignore Conditions |
| --- | --- |
| crate-ci/typos | [>= 1.30.a, < 1.31] |
</details>


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-04 16:39:00 +00:00
Marcin Tojek 975ea23d6f fix: display all available settings (#16798)
Fixes: https://github.com/coder/coder/issues/15420
2025-03-04 15:46:25 +01:00
Yevhenii Shcherbina 84881a0e98 test: fix flaky tests (#16799)
Relates to: https://github.com/coder/internal/issues/451

Create separate context with timeout for every subtest.
2025-03-04 08:44:48 -05:00
Cian Johnston e9f882220e feat(site): allow opening web terminal to container (#16797)
Co-authored-by: BrunoQuaresma <bruno_nonato_quaresma@hotmail.com>
2025-03-04 10:22:03 -03:00
Ethan d8561a62fc ci: avoid cancelling other nightly-gauntlet jobs on failure (#16795)
I saw in a failing nightly-gauntlet that the macOS+Postgres tests
failing caused the Windows tests to get cancelled:
https://github.com/coder/coder/actions/runs/13645971060

There's no harm in letting the other test run, and will let us catch
additional flakes & failures. If one job fails, the whole matrix will
still fail (once the remaining tests in the matrix have completed) and
the slack notification will still be sent.
[We previously made this
change](https://github.com/coder/coder/pull/8624) on our on-push `ci`
workflow.

Relevant documentation:
> jobs.<job_id>.strategy.fail-fast applies to the entire matrix. If
jobs.<job_id>.strategy.fail-fast is set to true or its expression
evaluates to true, GitHub will cancel all in-progress and queued jobs in
the matrix if any job in the matrix fails. This property defaults to
true.


https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategyfail-fast
2025-03-04 07:00:28 +02:00
ケイラ 17ad2849e4 fix: fix deployment settings navigation issues (#16780) 2025-03-03 15:48:17 -07:00
Hugo Dutka 24f3445e00 chore: track workspace resource monitors in telemetry (#16776)
Addresses https://github.com/coder/nexus/issues/195. Specifically, just
the "tracking templates" requirement:

> ## Tracking in templates
> To enable resource alerts, a user must add the resource_monitoring
block to a template's coder_agent resource. We'd like to track if
customers have any resource monitoring enabled on a per-deployment
basis. Even better, we could identify which templates are using resource
monitoring.
2025-03-03 18:41:01 +01:00
Mathias Fredriksson dfcd93b26e feat: enable agent connection reports by default, remove flag (#16778)
This change enables agent connection reports by default and removes the
experimental flag for enabling them.

Updates #15139
2025-03-03 18:37:28 +02:00
Hugo Dutka 95347b2b93 fix: allow orgs with default github provider (#16755)
This PR fixes 2 bugs:

## Problem 1

The server would fail to start when the default github provider was
configured and the flag `--oauth2-github-allowed-orgs` was set. The
error was

```
error: configure github oauth2: allow everyone and allowed orgs cannot be used together
```

This PR fixes it by enabling "allow everone" with the default provider
only if "allowed orgs" isn't set.

## Problem 2

The default github provider uses the device flow to authorize users, and
that's handled differently by our web UI than the standard oauth flow.
In particular, the web UI only handles JSON responses rather than HTTP
redirects. There were 2 code paths that returned redirects, and the PR
changes them to return JSON messages instead if the device flow is
configured.
2025-03-03 16:05:45 +01:00
Yevhenii Shcherbina b85ba586ee fix(coderd/database): consider tag sets when calculating queue position (#16685)
Relates to https://github.com/coder/coder/issues/15843

## PR Contents

- Reimplementation of the `GetProvisionerJobsByIDsWithQueuePosition` SQL
query to **take into account** provisioner job tags and provisioner
daemon tags.
- Unit tests covering different **tag sets**, **job statuses**, and
**job ordering** scenarios.

## Notes

- The original row order is preserved by introducing the `ordinality`
field.
- Unnecessary rows are filtered as early as possible to ensure that
expensive joins operate on a smaller dataset.
- A "fake" join with `provisioner_jobs` is added at the end to ensure
`sqlc.embed` compiles successfully.
- **Backward compatibility is preserved**—only the SQL query has been
updated, while the Go code remains unchanged.
2025-03-03 10:02:18 -05:00
Bruno Quaresma 7637d39528 feat: update default audit log avatar (#16774)
After update:

![image](https://github.com/user-attachments/assets/2ac6707f-2a56-45ec-a88f-651826776744)
2025-03-03 11:53:59 -03:00
Cian Johnston ca23abcc30 chore(cli): fix test flake in TestSSH_Container/NotFound (#16771)
If you hit the list containers endpoint with no containers running, the
response is different. This uses a mock lister to ensure a consistent
response from the agent endpoint.
2025-03-03 14:15:25 +00:00
Eng Zer Jun 04c33968cf refactor: replace golang.org/x/exp/slices with slices (#16772)
The experimental functions in `golang.org/x/exp/slices` are now
available in the standard library since Go 1.21.

Reference: https://go.dev/doc/go1.21#slices

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2025-03-04 00:46:49 +11:00
Ethan 88f0131abb fix: use dbtime in dbmem query to fix flake (#16773)
Closes https://github.com/coder/internal/issues/447.

The test was failing 30% of the time on Windows without the rounding
applied by `dbtime`. `dbtime` was used on the timestamps inserted into
the DB, but not within the query. Once using `dbtime` within the query
there were no failures in 200 runs.
2025-03-03 13:42:13 +00:00
Hugo Dutka 0f4f6bd147 docs: describe default sign up behavior with GitHub (#16765)
Document the sign up behavior with the default GitHub OAuth2 app.
2025-03-03 13:23:12 +01:00
Hugo Dutka 9c5d4966ee docs: suggest disabling the default GitHub OAuth2 provider on k8s (#16758)
For production deployments we recommend disabling the default GitHub
OAuth2 app managed by Coder. This PR mentions it in k8s installation
docs and the helm README so users can stumble upon it more easily.
2025-03-03 12:32:27 +01:00
Hugo Dutka a5842e5ad1 docs: document default GitHub OAuth2 configuration and device flow (#16663)
Document the changes made in https://github.com/coder/coder/pull/16629
and https://github.com/coder/coder/pull/16585.
2025-03-03 12:31:56 +01:00
Vincent Vielle c074f77a4f feat: add notifications inbox db (#16599)
This PR is linked [to the following
issue](https://github.com/coder/internal/issues/334).

The objective is to create the DB layer and migration for the new `Coder
Inbox`.
2025-03-03 10:12:48 +01:00
Thomas Kosiewski d0e2060692 feat(agent): add second SSH listener on port 22 (#16627)
Fixes: https://github.com/coder/internal/issues/377

Added an additional SSH listener on port 22, so the agent now listens on both, port one and port 22.

---
Change-Id: Ifd986b260f8ac317e37d65111cd4e0bd1dc38af8
Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-03-03 04:47:42 +01:00
Nick Fisher ca23abe12c feat(provisioner): add support for workspace_owner_rbac_roles (#16407)
Part of https://github.com/coder/terraform-provider-coder/pull/330

Adds support for the coder_workspace_owner.rbac_roles attribute
2025-03-02 14:54:44 -06:00
Guspan Tanadi fc2815cfdb docs: fix anchor and repo links (#16555) 2025-03-02 09:55:36 -06:00
Marcin Tojek 4216e283ec fix: editor: fallback to default entrypoint (#16757)
Related:
https://github.com/coder/coder/pull/16753#discussion_r1975558383
2025-02-28 17:14:42 +01:00
Marcin Tojek 930816fd0e fix: locate Terraform entrypoint file (#16753)
Fixes: https://github.com/coder/coder/issues/16360
2025-02-28 15:22:36 +01:00
Sas Swart e27953d2bc fix(site): add a beta badge for presets (#16751)
closes #16731 

This pull request adds a "beta" badge to the presets input field on the
workspace creation page.
2025-02-28 14:41:53 +02:00
Cian Johnston 6889ad2e5e fix(agent/agentcontainers): remove empty warning if no containers exist (#16748)
Fixes the current annoying response if no containers are running:
```
{"containers":null,"warnings":[""]}
```
2025-02-28 11:05:50 +00:00
Cian Johnston ec44f06f5c feat(cli): allow SSH command to connect to running container (#16726)
Fixes https://github.com/coder/coder/issues/16709 and
https://github.com/coder/coder/issues/16420

Adds the capability to`coder ssh` into a running container if `CODER_AGENT_DEVCONTAINERS_ENABLE=true`.

Notes:
* SFTP is currently not supported
* Haven't tested X11 container forwarding
* Haven't tested agent forwarding
2025-02-28 09:38:45 +00:00
Dean Sheather 64fec8bf0b feat: include winres metadata in Windows binaries (#16706)
Adds information like product/file version, description, product name
and copyright to compiled Windows binaries in dogfood and release
builds. Also adds an icon to the executable.

This is necessary for Coder Desktop to be able to check the version on
binaries.

### Before:

![image](https://github.com/user-attachments/assets/82351b63-6b23-4ef8-ab89-7f9e6dafeabd)

![image](https://github.com/user-attachments/assets/d17d8098-e330-4ac0-b104-31163f84279f)

### After:

![image](https://github.com/user-attachments/assets/0ba50afa-ad53-4ad2-b5e2-557358cda037)

![image](https://github.com/user-attachments/assets/d305cc27-e3f3-41a8-9098-498b71344faa)

![image](https://github.com/user-attachments/assets/42f74ace-bda1-414f-b514-68d4d928c958)

Closes https://github.com/coder/coder/issues/16693
2025-02-28 16:03:08 +11:00
Dean Sheather 3997eeee26 chore: update tailscale (#16737) 2025-02-28 04:35:56 +00:00
Dean Sheather b23e05b1fe fix(vpn): fail early if wintun.dll is not present (#16707)
Prevents the VPN startup from hanging for 5 minutes due to a startup
backoff if `wintun.dll` cannot be loaded.

Because the `wintun` package doesn't expose an easy `Load() error`
method for us, the only way for us to force it to load (without unwanted
side effects) is through `wintun.Version()` which doesn't return an
error message.

So, we call that function so the `wintun` package loads the DLL and
configures the logging properly, then we try to load the DLL ourselves.
`LoadLibraryEx` will not load the library multiple times and returns a
reference to the existing library.

Closes https://github.com/coder/coder-desktop-windows/issues/24
2025-02-28 15:20:00 +11:00
ケイラ 7e339021c1 chore: use org-scoped roles for organization groups and members e2e tests (#16691) 2025-02-27 12:55:30 -07:00
Marcin Tojek 0ea06012fc fix: handle undefined job while updating build progress (#16732)
Fixes: https://github.com/coder/coder/issues/15444
2025-02-27 20:30:11 +01:00
ケイラ 91a4a98c27 chore: add an unassign action for roles (#16728) 2025-02-27 10:39:06 -07:00
Jaayden Halko bf5b002829 fix: add org role read permissions to site wide template admins and auditors (#16733)
resolves coder/internal#388

Since site-wide admins and auditors are able to access the members page
of any org, they should have read access to org roles
2025-02-27 12:28:43 -05:00
Jaayden Halko 464fccd807 chore: create collapsible summary component (#16705)
This is based on the Figma designs here:
https://www.figma.com/design/WfqIgsTFXN2BscBSSyXWF8/Coder-kit?node-id=507-1525&m=dev

---------

Co-authored-by: Steven Masley <stevenmasley@gmail.com>
2025-02-27 12:20:33 -05:00
Steven Masley cccdf1ecac feat: implement WorkspaceCreationBan org role (#16686)
Using negative permissions, this role prevents a user's ability to
create & delete a workspace within a given organization.

Workspaces are uniquely owned by an org and a user, so the org has to
supercede the user permission with a negative permission.

# Use case

Organizations must be able to restrict a member's ability to create a
workspace. This permission is implicitly granted (see
https://github.com/coder/coder/issues/16546#issuecomment-2655437860).

To revoke this permission, the solution chosen was to use negative
permissions in a built in role called `WorkspaceCreationBan`.

# Rational

Using negative permissions is new territory, and not ideal. However,
workspaces are in a unique position.

Workspaces have 2 owners. The organization and the user. To prevent
users from creating a workspace in another organization, an [implied
negative
permission](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/policy.rego#L172-L192)
is used. So the truth table looks like: _how to read this table
[here](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/README.md#roles)_

| Role (example)  | Site | Org  | User | Result |
|-----------------|------|------|------|--------|
| non-org-member  | \_   | N    | YN\_ | N      |
| user            | \_   | \_   | Y    | Y      |
| WorkspaceBan    | \_   | N    | Y    | Y      |
| unauthenticated | \_   | \_   | \_   | N      |


This new role, `WorkspaceCreationBan` is the same truth table condition
as if the user was not a member of the organization (when doing a
workspace create/delete). So this behavior **is not entirely new**.

<details>

<summary>How to do it without a negative permission</summary>

The alternate approach would be to remove the implied permission, and
grant it via and organization role. However this would add new behavior
that an organizational role has the ability to grant a user permissions
on their own resources?

It does not make sense for an org role to prevent user from changing
their profile information for example. So the only option is to create a
new truth table column for resources that are owned by both an
organization and a user.

| Role (example)  | Site | Org  |User+Org| User | Result |
|-----------------|------|------|--------|------|--------|
| non-org-member  | \_   | N    |  \_    | \_   | N      |
| user            | \_   | \_   |  \_    | \_   | N      |
| WorkspaceAllow  | \_   | \_   |   Y    | \_   | Y      |
| unauthenticated | \_   | \_   |  \_    | \_   | N      |

Now a user has no opinion on if they can create a workspace, which feels
a little wrong. A user should have the authority over what is theres.

There is fundamental _philosophical_ question of "Who does a workspace
belong to?". The user has some set of autonomy, yet it is the
organization that controls it's existence. A head scratcher 🤔

</details>

## Will we need more negative built in roles?

There are few resources that have shared ownership. Only
`ResourceOrganizationMember` and `ResourceGroupMember`. Since negative
permissions is intended to revoke access to a shared resource, then
**no.** **This is the only one we need**.

Classic resources like `ResourceTemplate` are entirely controlled by the
Organization permissions. And resources entirely in the user control
(like user profile) are only controlled by `User` permissions.


![Uploading Screenshot 2025-02-26 at 22.26.52.png…]()

---------

Co-authored-by: Jaayden Halko <jaayden.halko@gmail.com>
Co-authored-by: ケイラ <mckayla@hey.com>
2025-02-27 06:23:18 -05:00
Mathias Fredriksson 4ba5a8a2ba feat(agent): add connection reporting for SSH and reconnecting PTY (#16652)
Updates #15139
2025-02-27 10:45:45 +00:00
Danielle Maywood 6dd51f92fb chore: test metricscache on postgres (#16711)
metricscache_test has been running tests against dbmem only, instead of
against postgres. Unfortunately the implementations of
GetTemplateAverageBuildTime have diverged between dbmem and postgres.
This change gets the tests working on Postgres and test for the
behaviour postgres provides.
2025-02-27 09:43:51 +00:00
Cian Johnston 95363c9041 fix(enterprise/coderd): remove useless provisioner daemon id from request (#16723)
`ServeProvisionerDaemonRequest` has had an ID field for quite a while
now.
This field is only used for telemetry purposes; the actual daemon ID is
created upon insertion in the database. There's no reason to set it, and
it's confusing to do so. Deprecating the field and removing references
to it.
2025-02-27 09:08:08 +00:00
Edward Angert b3d675532f docs: copy edit early access section in feature-stages doc (#16730)
- copy edit EA section with @mattvollmer 's suggestions
- ran the script that updates the list of experiments

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-02-27 09:20:03 +05:00
Edward Angert 5cdc13ba9e docs: fix broken links in feature-stages (#16727)
fix broken links introduced by #16719

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
2025-02-26 22:42:46 +00:00
Jaayden Halko 6b69635140 chore: warn user without permissions to view org members (#16721)
resolves coder/internal#392

In situations where a user accesses the org members without any
permissions beyond that of a normal member, they will only be able to
see themselves in the list of members.

This PR shows a warning to users who arrive at the members page in this
situation.

<img width="1145" alt="Screenshot 2025-02-26 at 18 36 59"
src="https://github.com/user-attachments/assets/16ad6ce1-2aa9-4719-bdae-914aff0fcd52"
/>
2025-02-26 17:03:23 -05:00
Cian Johnston 2aa749a7f0 chore(cli): fix test flake caused by agent connect race (#16725)
Fixes test flake seen here:
https://github.com/coder/coder/actions/runs/13552012547/job/37877778883

```
    exp_rpty_test.go:96: 
        	Error Trace:	/home/runner/work/coder/coder/cli/exp_rpty_test.go:96
        	            				/home/runner/work/coder/coder/cli/ssh_test.go:1963
        	            				/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.9.linux-amd64/src/runtime/asm_amd64.s:1695
        	Error:      	Received unexpected error:
        	            	running command "coder exp rpty": GET http://localhost:37991/api/v2/workspaceagents/3785b98f-0589-47d2-a3c8-33a55a6c5b29/containers: unexpected status code 400: Agent state is "connecting", it must be in the "connected" state.
        	Test:       	TestExpRpty/Container
```
2025-02-26 21:10:39 +00:00
Edward Angert 81ef9e9e80 docs: document new feature stages (#16719)
- [x] translate notes to docs
- [x] move to Home > About > Feature Stages
- [x] decide on bullet point summaries (👍 👎  in comment)

### OOS for this PR

add support page that describes how users can get support. currently,
[this help
article](https://help.coder.com/hc/en-us/articles/25308666965783-Get-Help-with-Coder)
is the only thing that pops up and includes that `Users with valid Coder
licenses can submit tickets` but doesn't show how, nor does it include
the support bundle docs (link or content). it'd be good to have these
things relate to each other

## preview


[preview](https://coder.com/docs/@feature-stages/contributing/feature-stages)

---------

Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
Co-authored-by: Ben Potter <ben@coder.com>
2025-02-26 15:43:02 -05:00
Jaayden Halko 1cb864bc1b fix: allow viewOrgRoles for custom roles page (#16722)
Users with viewOrgRoles should be able to see customs roles page as this
matches the left sidebar permissions.
2025-02-26 14:39:08 -05:00
Michael Vincent Patterson 5295902596 docs: clarified prometheus integration behavior (#16724)
Closes issue #16538 
Updated docs to explain Behavior of enabling Prometheus
2025-02-26 19:30:41 +00:00
Mathias Fredriksson 7cd6e9cdd6 fix: return provisioners in desc order and add limit to cli (#16720) 2025-02-26 21:06:51 +02:00
Bruno Quaresma 7c035a4d98 fix: remove provisioners from deployment sidebar (#16717)
Provisioners should be only under orgs. This is a left over from a
previous provisioner refactoring.
2025-02-26 14:20:47 -03:00
Mathias Fredriksson b94d2cb8d4 fix(coderd): handle deletes and links for new agent/app audit resources (#16670)
These code-paths were overlooked in #16493.
2025-02-26 19:16:54 +02:00
Bruno Quaresma f1b357d6f2 feat: support session audit log (#16703)
Related to https://github.com/coder/coder/issues/15139

Demo:
<img width="1213" alt="Screenshot 2025-02-25 at 16 27 12"
src="https://github.com/user-attachments/assets/9995a68d-5cd4-4b95-9523-dfd5bf4ff48d"
/>

---------

Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
2025-02-26 14:13:11 -03:00
Cian Johnston 2971957b88 ci: also restart tagged provisioner deployment (#16716)
Forgot to add this to CI a while ago, and it only recently became
apparent!
2025-02-26 17:12:51 +00:00
Marcin Tojek a2cc1b896f fix: display premium banner on audit page when license inactive (#16713)
Fixes: https://github.com/coder/coder/issues/14798
2025-02-26 14:16:48 +01:00
Cian Johnston c5a265fbc3 feat(cli): add experimental rpty command (#16700)
Relates to https://github.com/coder/coder/issues/16419

Builds upon https://github.com/coder/coder/pull/16638 and adds a command
`exp rpty` that allows you to open a ReconnectingPTY session to an
agent.

This ultimately allows us to add an integration-style CLI test to verify
the functionality added in #16638 .
2025-02-26 12:32:57 +00:00
Thomas Kosiewski 38c0e8a086 fix(agent/agentssh): ensure RSA key generation always produces valid keys (#16694)
Modify the RSA key generation algorithm to check that GCD(e, p-1) = 1 and
GCD(e, q-1) = 1 when selecting prime numbers, ensuring that e and φ(n) 
are coprime. This prevents ModInverse from returning nil, which would 
cause private key generation to fail and result in a panic when `Precompute` is called.

Change-Id: I0a453e1e1f8c638e40e7a4b87a6d0d7299e1cb5d
Signed-off-by: Thomas Kosiewski <tk@coder.com>
2025-02-26 11:45:35 +01:00
Cian Johnston 172e52317c feat(agent): wire up agentssh server to allow exec into container (#16638)
Builds on top of https://github.com/coder/coder/pull/16623/ and wires up
the ReconnectingPTY server. This does nothing to wire up the web
terminal yet but the added test demonstrates the functionality working.

Other changes:
* Refactors and moves the `SystemEnvInfo` interface to the
`agent/usershell` package to address follow-up from
https://github.com/coder/coder/pull/16623#discussion_r1967580249
* Marks `usershellinfo.Get` as deprecated. Consumers should use the
`EnvInfoer` interface instead.

---------

Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
Co-authored-by: Danny Kopping <danny@coder.com>
2025-02-26 09:03:27 +00:00
2050 changed files with 108574 additions and 25791 deletions
+124
View File
@@ -0,0 +1,124 @@
# Cursor Rules
This project is called "Coder" - an application for managing remote development environments.
Coder provides a platform for creating, managing, and using remote development environments (also known as Cloud Development Environments or CDEs). It leverages Terraform to define and provision these environments, which are referred to as "workspaces" within the project. The system is designed to be extensible, secure, and provide developers with a seamless remote development experience.
## Core Architecture
The heart of Coder is a control plane that orchestrates the creation and management of workspaces. This control plane interacts with separate Provisioner processes over gRPC to handle workspace builds. The Provisioners consume workspace definitions and use Terraform to create the actual infrastructure.
The CLI package serves dual purposes - it can be used to launch the control plane itself and also provides client functionality for users to interact with an existing control plane instance. All user-facing frontend code is developed in TypeScript using React and lives in the `site/` directory.
The database layer uses PostgreSQL with SQLC for generating type-safe database code. Database migrations are carefully managed to ensure both forward and backward compatibility through paired `.up.sql` and `.down.sql` files.
## API Design
Coder's API architecture combines REST and gRPC approaches. The REST API is defined in `coderd/coderd.go` and uses Chi for HTTP routing. This provides the primary interface for the frontend and external integrations.
Internal communication with Provisioners occurs over gRPC, with service definitions maintained in `.proto` files. This separation allows for efficient binary communication with the components responsible for infrastructure management while providing a standard REST interface for human-facing applications.
## Network Architecture
Coder implements a secure networking layer based on Tailscale's Wireguard implementation. The `tailnet` package provides connectivity between workspace agents and clients through DERP (Designated Encrypted Relay for Packets) servers when direct connections aren't possible. This creates a secure overlay network allowing access to workspaces regardless of network topology, firewalls, or NAT configurations.
### Tailnet and DERP System
The networking system has three key components:
1. **Tailnet**: An overlay network implemented in the `tailnet` package that provides secure, end-to-end encrypted connections between clients, the Coder server, and workspace agents.
2. **DERP Servers**: These relay traffic when direct connections aren't possible. Coder provides several options:
- A built-in DERP server that runs on the Coder control plane
- Integration with Tailscale's global DERP infrastructure
- Support for custom DERP servers for lower latency or offline deployments
3. **Direct Connections**: When possible, the system establishes peer-to-peer connections between clients and workspaces using STUN for NAT traversal. This requires both endpoints to send UDP traffic on ephemeral ports.
### Workspace Proxies
Workspace proxies (in the Enterprise edition) provide regional relay points for browser-based connections, reducing latency for geo-distributed teams. Key characteristics:
- Deployed as independent servers that authenticate with the Coder control plane
- Relay connections for SSH, workspace apps, port forwarding, and web terminals
- Do not make direct database connections
- Managed through the `coder wsproxy` commands
- Implemented primarily in the `enterprise/wsproxy/` package
## Agent System
The workspace agent runs within each provisioned workspace and provides core functionality including:
- SSH access to workspaces via the `agentssh` package
- Port forwarding
- Terminal connectivity via the `pty` package for pseudo-terminal support
- Application serving
- Healthcheck monitoring
- Resource usage reporting
Agents communicate with the control plane using the tailnet system and authenticate using secure tokens.
## Workspace Applications
Workspace applications (or "apps") provide browser-based access to services running within workspaces. The system supports:
- HTTP(S) and WebSocket connections
- Path-based or subdomain-based access URLs
- Health checks to monitor application availability
- Different sharing levels (owner-only, authenticated users, or public)
- Custom icons and display settings
The implementation is primarily in the `coderd/workspaceapps/` directory with components for URL generation, proxying connections, and managing application state.
## Implementation Details
The project structure separates frontend and backend concerns. React components and pages are organized in the `site/src/` directory, with Jest used for testing. The backend is primarily written in Go, with a strong emphasis on error handling patterns and test coverage.
Database interactions are carefully managed through migrations in `coderd/database/migrations/` and queries in `coderd/database/queries/`. All new queries require proper database authorization (dbauthz) implementation to ensure that only users with appropriate permissions can access specific resources.
## Authorization System
The database authorization (dbauthz) system enforces fine-grained access control across all database operations. It uses role-based access control (RBAC) to validate user permissions before executing database operations. The `dbauthz` package wraps the database store and performs authorization checks before returning data. All database operations must pass through this layer to ensure security.
## Testing Framework
The codebase has a comprehensive testing approach with several key components:
1. **Parallel Testing**: All tests must use `t.Parallel()` to run concurrently, which improves test suite performance and helps identify race conditions.
2. **coderdtest Package**: This package in `coderd/coderdtest/` provides utilities for creating test instances of the Coder server, setting up test users and workspaces, and mocking external components.
3. **Integration Tests**: Tests often span multiple components to verify system behavior, such as template creation, workspace provisioning, and agent connectivity.
4. **Enterprise Testing**: Enterprise features have dedicated test utilities in the `coderdenttest` package.
## Open Source and Enterprise Components
The repository contains both open source and enterprise components:
- Enterprise code lives primarily in the `enterprise/` directory
- Enterprise features focus on governance, scalability (high availability), and advanced deployment options like workspace proxies
- The boundary between open source and enterprise is managed through a licensing system
- The same core codebase supports both editions, with enterprise features conditionally enabled
## Development Philosophy
Coder emphasizes clear error handling, with specific patterns required:
- Concise error messages that avoid phrases like "failed to"
- Wrapping errors with `%w` to maintain error chains
- Using sentinel errors with the "err" prefix (e.g., `errNotFound`)
All tests should run in parallel using `t.Parallel()` to ensure efficient testing and expose potential race conditions. The codebase is rigorously linted with golangci-lint to maintain consistent code quality.
Git contributions follow a standard format with commit messages structured as `type: <message>`, where type is one of `feat`, `fix`, or `chore`.
## Development Workflow
Development can be initiated using `scripts/develop.sh` to start the application after making changes. Database schema updates should be performed through the migration system using `create_migration.sh <name>` to generate migration files, with each `.up.sql` migration paired with a corresponding `.down.sql` that properly reverts all changes.
If the development database gets into a bad state, it can be completely reset by removing the PostgreSQL data directory with `rm -rf .coderv2/postgres`. This will destroy all data in the development database, requiring you to recreate any test users, templates, or workspaces after restarting the application.
Code generation for the database layer uses `coderd/database/generate.sh`, and developers should refer to `sqlc.yaml` for the appropriate style and patterns to follow when creating new queries or tables.
The focus should always be on maintaining security through proper database authorization, clean error handling, and comprehensive test coverage to ensure the platform remains robust and reliable.
+2
View File
@@ -1,5 +1,7 @@
# Generated files
agent/agentcontainers/acmock/acmock.go linguist-generated=true
agent/agentcontainers/dcspec/dcspec_gen.go linguist-generated=true
agent/agentcontainers/testdata/devcontainercli/*/*.log linguist-generated=true
coderd/apidoc/docs.go linguist-generated=true
docs/reference/api/*.md linguist-generated=true
docs/reference/cli/*.md linguist-generated=true
+3
View File
@@ -21,5 +21,8 @@ ignorePatterns:
- pattern: "linux.die.net/man"
- pattern: "www.gnu.org"
- pattern: "wiki.ubuntu.com"
- pattern: "mutagen.io"
- pattern: "docs.github.com"
- pattern: "claude.ai"
aliveStatusCodes:
- 200
+1 -1
View File
@@ -1,6 +1,6 @@
name: "🐞 Bug"
description: "File a bug report."
title: "<title>"
title: "bug: "
labels: ["needs-triage"]
body:
- type: checkboxes
@@ -0,0 +1,10 @@
name: "Install cosign"
description: |
Cosign Github Action.
runs:
using: "composite"
steps:
- name: Install cosign
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
with:
cosign-release: "v2.4.3"
+10
View File
@@ -0,0 +1,10 @@
name: "Install syft"
description: |
Downloads Syft to the Action tool cache and provides a reference.
runs:
using: "composite"
steps:
- name: Install syft
uses: anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
with:
syft-version: "v1.20.0"
+57
View File
@@ -0,0 +1,57 @@
name: "Setup Go Paths"
description: Overrides Go paths like GOCACHE and GOMODCACHE to use temporary directories.
outputs:
gocache:
description: "Value of GOCACHE"
value: ${{ steps.paths.outputs.gocache }}
gomodcache:
description: "Value of GOMODCACHE"
value: ${{ steps.paths.outputs.gomodcache }}
gopath:
description: "Value of GOPATH"
value: ${{ steps.paths.outputs.gopath }}
gotmp:
description: "Value of GOTMPDIR"
value: ${{ steps.paths.outputs.gotmp }}
cached-dirs:
description: "Go directories that should be cached between CI runs"
value: ${{ steps.paths.outputs.cached-dirs }}
runs:
using: "composite"
steps:
- name: Override Go paths
id: paths
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
with:
script: |
const path = require('path');
// RUNNER_TEMP should be backed by a RAM disk on Windows if
// coder/setup-ramdisk-action was used
const runnerTemp = process.env.RUNNER_TEMP;
const gocacheDir = path.join(runnerTemp, 'go-cache');
const gomodcacheDir = path.join(runnerTemp, 'go-mod-cache');
const gopathDir = path.join(runnerTemp, 'go-path');
const gotmpDir = path.join(runnerTemp, 'go-tmp');
core.exportVariable('GOCACHE', gocacheDir);
core.exportVariable('GOMODCACHE', gomodcacheDir);
core.exportVariable('GOPATH', gopathDir);
core.exportVariable('GOTMPDIR', gotmpDir);
core.setOutput('gocache', gocacheDir);
core.setOutput('gomodcache', gomodcacheDir);
core.setOutput('gopath', gopathDir);
core.setOutput('gotmp', gotmpDir);
const cachedDirs = `${gocacheDir}\n${gomodcacheDir}`;
core.setOutput('cached-dirs', cachedDirs);
- name: Create directories
shell: bash
run: |
set -e
mkdir -p "$GOCACHE"
mkdir -p "$GOMODCACHE"
mkdir -p "$GOPATH"
mkdir -p "$GOTMPDIR"
@@ -0,0 +1,14 @@
name: "Setup Go tools"
description: |
Set up tools for `make gen`, `offlinedocs` and Schmoder CI.
runs:
using: "composite"
steps:
- name: go install tools
shell: bash
run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30
go install storj.io/drpc/cmd/protoc-gen-go-drpc@v0.0.34
go install golang.org/x/tools/cmd/goimports@v0.31.0
go install github.com/mikefarah/yq/v4@v4.44.3
go install go.uber.org/mock/mockgen@v0.5.0
+14 -3
View File
@@ -4,18 +4,29 @@ description: |
inputs:
version:
description: "The Go version to use."
default: "1.22.8"
default: "1.24.6"
use-preinstalled-go:
description: "Whether to use preinstalled Go."
default: "false"
use-cache:
description: "Whether to use the cache."
default: "true"
runs:
using: "composite"
steps:
- name: Setup Go
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
with:
go-version: ${{ inputs.version }}
go-version: ${{ inputs.use-preinstalled-go == 'false' && inputs.version || '' }}
cache: ${{ inputs.use-cache }}
- name: Install gotestsum
shell: bash
run: go install gotest.tools/gotestsum@latest
run: go install gotest.tools/gotestsum@0d9599e513d70e5792bb9334869f82f6e8b53d4d # main as of 2025-05-15
- name: Install mtimehash
shell: bash
run: go install github.com/slsyy/mtimehash/cmd/mtimehash@a6b5da4ed2c4a40e7b805534b004e9fde7b53ce0 # v1.0.0
# It isn't necessary that we ever do this, but it helps
# separate the "setup" from the "run" times.
-27
View File
@@ -1,27 +0,0 @@
name: "Setup ImDisk"
if: runner.os == 'Windows'
description: |
Sets up the ImDisk toolkit for Windows and creates a RAM disk on drive R:.
runs:
using: "composite"
steps:
- name: Download ImDisk
if: runner.os == 'Windows'
shell: bash
run: |
mkdir imdisk
cd imdisk
curl -L -o files.cab https://github.com/coder/imdisk-artifacts/raw/92a17839ebc0ee3e69be019f66b3e9b5d2de4482/files.cab
curl -L -o install.bat https://github.com/coder/imdisk-artifacts/raw/92a17839ebc0ee3e69be019f66b3e9b5d2de4482/install.bat
cd ..
- name: Install ImDisk
shell: cmd
run: |
cd imdisk
install.bat /silent
- name: Create RAM Disk
shell: cmd
run: |
imdisk -a -s 4096M -m R: -p "/fs:ntfs /q /y"
+1 -1
View File
@@ -7,5 +7,5 @@ runs:
- name: Install Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
with:
terraform_version: 1.10.5
terraform_version: 1.11.4
terraform_wrapper: false
@@ -0,0 +1,50 @@
name: "Download Test Cache"
description: |
Downloads the test cache and outputs today's cache key.
A PR job can use a cache if it was created by its base branch, its current
branch, or the default branch.
https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
outputs:
cache-key:
description: "Today's cache key"
value: ${{ steps.vars.outputs.cache-key }}
inputs:
key-prefix:
description: "Prefix for the cache key"
required: true
cache-path:
description: "Path to the cache directory"
required: true
# This path is defined in testutil/cache.go
default: "~/.cache/coderv2-test"
runs:
using: "composite"
steps:
- name: Get date values and cache key
id: vars
shell: bash
run: |
export YEAR_MONTH=$(date +'%Y-%m')
export PREV_YEAR_MONTH=$(date -d 'last month' +'%Y-%m')
export DAY=$(date +'%d')
echo "year-month=$YEAR_MONTH" >> $GITHUB_OUTPUT
echo "prev-year-month=$PREV_YEAR_MONTH" >> $GITHUB_OUTPUT
echo "cache-key=${{ inputs.key-prefix }}-${YEAR_MONTH}-${DAY}" >> $GITHUB_OUTPUT
# TODO: As a cost optimization, we could remove caches that are older than
# a day or two. By default, depot keeps caches for 14 days, which isn't
# necessary for the test cache.
# https://depot.dev/docs/github-actions/overview#cache-retention-policy
- name: Download test cache
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ${{ inputs.cache-path }}
key: ${{ steps.vars.outputs.cache-key }}
# > If there are multiple partial matches for a restore key, the action returns the most recently created cache.
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#matching-a-cache-key
# The second restore key allows non-main branches to use the cache from the previous month.
# This prevents PRs from rebuilding the cache on the first day of the month.
# It also makes sure that once a month, the cache is fully reset.
restore-keys: |
${{ inputs.key-prefix }}-${{ steps.vars.outputs.year-month }}-
${{ github.ref != 'refs/heads/main' && format('{0}-{1}-', inputs.key-prefix, steps.vars.outputs.prev-year-month) || '' }}
@@ -0,0 +1,20 @@
name: "Upload Test Cache"
description: Uploads the test cache. Only works on the main branch.
inputs:
cache-key:
description: "Cache key"
required: true
cache-path:
description: "Path to the cache directory"
required: true
# This path is defined in testutil/cache.go
default: "~/.cache/coderv2-test"
runs:
using: "composite"
steps:
- name: Upload test cache
if: ${{ github.ref == 'refs/heads/main' }}
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ${{ inputs.cache-path }}
key: ${{ inputs.cache-key }}
+41 -2
View File
@@ -10,6 +10,8 @@ runs:
steps:
- shell: bash
run: |
set -e
owner=${{ github.repository_owner }}
echo "owner: $owner"
if [[ $owner != "coder" ]]; then
@@ -21,8 +23,45 @@ runs:
echo "No API key provided, skipping..."
exit 0
fi
npm install -g @datadog/datadog-ci@2.21.0
datadog-ci junit upload --service coder ./gotests.xml \
BINARY_VERSION="v2.48.0"
BINARY_HASH_WINDOWS="b7bebb8212403fddb1563bae84ce5e69a70dac11e35eb07a00c9ef7ac9ed65ea"
BINARY_HASH_MACOS="e87c808638fddb21a87a5c4584b68ba802965eb0a593d43959c81f67246bd9eb"
BINARY_HASH_LINUX="5e700c465728fff8313e77c2d5ba1ce19a736168735137e1ddc7c6346ed48208"
TMP_DIR=$(mktemp -d)
if [[ "${{ runner.os }}" == "Windows" ]]; then
BINARY_PATH="${TMP_DIR}/datadog-ci.exe"
BINARY_URL="https://github.com/DataDog/datadog-ci/releases/download/${BINARY_VERSION}/datadog-ci_win-x64"
elif [[ "${{ runner.os }}" == "macOS" ]]; then
BINARY_PATH="${TMP_DIR}/datadog-ci"
BINARY_URL="https://github.com/DataDog/datadog-ci/releases/download/${BINARY_VERSION}/datadog-ci_darwin-arm64"
elif [[ "${{ runner.os }}" == "Linux" ]]; then
BINARY_PATH="${TMP_DIR}/datadog-ci"
BINARY_URL="https://github.com/DataDog/datadog-ci/releases/download/${BINARY_VERSION}/datadog-ci_linux-x64"
else
echo "Unsupported OS: ${{ runner.os }}"
exit 1
fi
echo "Downloading DataDog CI binary version ${BINARY_VERSION} for ${{ runner.os }}..."
curl -sSL "$BINARY_URL" -o "$BINARY_PATH"
if [[ "${{ runner.os }}" == "Windows" ]]; then
echo "$BINARY_HASH_WINDOWS $BINARY_PATH" | sha256sum --check
elif [[ "${{ runner.os }}" == "macOS" ]]; then
echo "$BINARY_HASH_MACOS $BINARY_PATH" | shasum -a 256 --check
elif [[ "${{ runner.os }}" == "Linux" ]]; then
echo "$BINARY_HASH_LINUX $BINARY_PATH" | sha256sum --check
fi
# Make binary executable (not needed for Windows)
if [[ "${{ runner.os }}" != "Windows" ]]; then
chmod +x "$BINARY_PATH"
fi
"$BINARY_PATH" junit upload --service coder ./gotests.xml \
--tags os:${{runner.os}} --tags runner_name:${{runner.name}}
env:
DATADOG_API_KEY: ${{ inputs.api-key }}
+20 -1
View File
@@ -37,7 +37,8 @@ updates:
# Update our Dockerfile.
- package-ecosystem: "docker"
directories:
- "/dogfood/contents"
- "/dogfood/coder"
- "/dogfood/coder-envbuilder"
- "/scripts"
- "/examples/templates/docker/build"
- "/examples/parameters/build"
@@ -103,3 +104,21 @@ updates:
update-types:
- version-update:semver-major
open-pull-requests-limit: 15
- package-ecosystem: "terraform"
directories:
- "dogfood/*/"
- "examples/templates/*/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore"
groups:
coder:
patterns:
- "registry.coder.com/coder/*/coder"
labels: []
ignore:
- dependency-name: "*"
update-types:
- version-update:semver-major
+436 -131
View File
@@ -24,7 +24,7 @@ jobs:
docs-only: ${{ steps.filter.outputs.docs_count == steps.filter.outputs.all_count }}
docs: ${{ steps.filter.outputs.docs }}
go: ${{ steps.filter.outputs.go }}
ts: ${{ steps.filter.outputs.ts }}
site: ${{ steps.filter.outputs.site }}
k8s: ${{ steps.filter.outputs.k8s }}
ci: ${{ steps.filter.outputs.ci }}
db: ${{ steps.filter.outputs.db }}
@@ -34,7 +34,7 @@ jobs:
tailnet-integration: ${{ steps.filter.outputs.tailnet-integration }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -92,9 +92,8 @@ jobs:
gomod:
- "go.mod"
- "go.sum"
ts:
site:
- "site/**"
- "Makefile"
k8s:
- "helm/**"
- "scripts/Dockerfile"
@@ -155,7 +154,7 @@ jobs:
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -172,13 +171,13 @@ jobs:
- name: Get golangci-lint cache dir
run: |
linter_ver=$(egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/contents/Dockerfile | cut -d '=' -f 2)
linter_ver=$(egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/coder/Dockerfile | cut -d '=' -f 2)
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$linter_ver
dir=$(golangci-lint cache status | awk '/Dir/ { print $2 }')
echo "LINT_CACHE_DIR=$dir" >> $GITHUB_ENV
- name: golangci-lint cache
uses: actions/cache@0c907a75c2c80ebcb7f088228285e798b750cf8f # v4.2.1
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
${{ env.LINT_CACHE_DIR }}
@@ -188,7 +187,7 @@ jobs:
# Check for any typos
- name: Check for typos
uses: crate-ci/typos@212923e4ff05b7fc2294a204405eec047b807138 # v1.29.9
uses: crate-ci/typos@0f0ccba9ed1df83948f0c15026e4f5ccfce46109 # v1.32.0
with:
config: .github/workflows/typos.toml
@@ -224,10 +223,10 @@ jobs:
gen:
timeout-minutes: 8
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
if: always()
if: ${{ !cancelled() }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -249,12 +248,7 @@ jobs:
uses: ./.github/actions/setup-tf
- name: go install tools
run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30
go install storj.io/drpc/cmd/protoc-gen-go-drpc@v0.0.34
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/mikefarah/yq/v4@v4.44.3
go install go.uber.org/mock/mockgen@v0.5.0
uses: ./.github/actions/setup-go-tools
- name: Install Protoc
run: |
@@ -267,18 +261,15 @@ jobs:
popd
- name: make gen
# no `-j` flag as `make` fails with:
# coderd/rbac/object_gen.go:1:1: syntax error: package statement must be first
run: "make --output-sync -B gen"
- name: make update-golden-files
run: |
# Remove golden files to detect discrepancy in generated files.
make clean/golden-files
# Notifications require DB, we could start a DB instance here but
# let's just restore for now.
git checkout -- coderd/notifications/testdata/rendered-templates
# As above, skip `-j` flag.
make --output-sync -B update-golden-files
# no `-j` flag as `make` fails with:
# coderd/rbac/object_gen.go:1:1: syntax error: package statement must be first
make --output-sync -B gen
- name: Check for unstaged files
run: ./scripts/check_unstaged.sh
@@ -290,7 +281,7 @@ jobs:
timeout-minutes: 7
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -302,6 +293,9 @@ jobs:
- name: Setup Node
uses: ./.github/actions/setup-node
- name: Check Go version
run: IGNORE_NIX=true ./scripts/check_go_versions.sh
# Use default Go version
- name: Setup Go
uses: ./.github/actions/setup-go
@@ -318,7 +312,7 @@ jobs:
run: ./scripts/check_unstaged.sh
test-go:
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'depot-macos-latest' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'windows-latest-16-cores' || matrix.os }}
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'depot-macos-latest' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'depot-windows-2022-16' || matrix.os }}
needs: changes
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
timeout-minutes: 20
@@ -331,21 +325,43 @@ jobs:
- windows-2022
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
# Harden Runner is only supported on Ubuntu runners.
if: runner.os == 'Linux'
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
# Set up RAM disks to speed up the rest of the job. This action is in
# a separate repository to allow its use before actions/checkout.
- name: Setup RAM Disks
if: runner.os == 'Windows'
uses: coder/setup-ramdisk-action@e1100847ab2d7bcd9d14bcda8f2d1b0f07b36f1b
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
- name: Setup Go Paths
uses: ./.github/actions/setup-go-paths
- name: Setup Go
uses: ./.github/actions/setup-go
with:
# Runners have Go baked-in and Go will automatically
# download the toolchain configured in go.mod, so we don't
# need to reinstall it. It's faster on Windows runners.
use-preinstalled-go: ${{ runner.os == 'Windows' }}
- name: Setup Terraform
uses: ./.github/actions/setup-tf
- name: Download Test Cache
id: download-cache
uses: ./.github/actions/test-cache/download
with:
key-prefix: test-go-${{ runner.os }}-${{ runner.arch }}
- name: Test with Mock Database
id: test
shell: bash
@@ -367,62 +383,13 @@ jobs:
touch ~/.bash_profile && echo "export BASH_SILENCE_DEPRECATION_WARNING=1" >> ~/.bash_profile
fi
export TS_DEBUG_DISCO=true
gotestsum --junitfile="gotests.xml" --jsonfile="gotests.json" \
--packages="./..." -- $PARALLEL_FLAG -short -failfast
gotestsum --junitfile="gotests.xml" --jsonfile="gotests.json" --rerun-fails=2 \
--packages="./..." -- $PARALLEL_FLAG -short
- name: Upload test stats to Datadog
timeout-minutes: 1
continue-on-error: true
uses: ./.github/actions/upload-datadog
if: success() || failure()
- name: Upload Test Cache
uses: ./.github/actions/test-cache/upload
with:
api-key: ${{ secrets.DATADOG_API_KEY }}
# We don't run the full test-suite for Windows & MacOS, so we just run the CLI tests on every PR.
# We run the test suite in test-go-pg, including CLI.
test-cli:
runs-on: ${{ matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'depot-macos-latest' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'windows-latest-16-cores' || matrix.os }}
needs: changes
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
strategy:
matrix:
os:
- macos-latest
- windows-2022
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
- name: Setup Go
uses: ./.github/actions/setup-go
- name: Setup Terraform
uses: ./.github/actions/setup-tf
# Sets up the ImDisk toolkit for Windows and creates a RAM disk on drive R:.
- name: Setup ImDisk
if: runner.os == 'Windows'
uses: ./.github/actions/setup-imdisk
- name: Test CLI
env:
TS_DEBUG_DISCO: "true"
LC_CTYPE: "en_US.UTF-8"
LC_ALL: "en_US.UTF-8"
shell: bash
run: |
# By default Go will use the number of logical CPUs, which
# is a fine default.
PARALLEL_FLAG=""
make test-cli
cache-key: ${{ steps.download-cache.outputs.cache-key }}
- name: Upload test stats to Datadog
timeout-minutes: 1
@@ -433,7 +400,9 @@ jobs:
api-key: ${{ secrets.DATADOG_API_KEY }}
test-go-pg:
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || matrix.os }}
# make sure to adjust NUM_PARALLEL_PACKAGES and NUM_PARALLEL_TESTS below
# when changing runner sizes
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || matrix.os && matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'depot-macos-latest' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'depot-windows-2022-16' || matrix.os }}
needs: changes
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
# This timeout must be greater than the timeout set by `go test` in
@@ -445,27 +414,78 @@ jobs:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-2022
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
# macOS indexes all new files in the background. Our Postgres tests
# create and destroy thousands of databases on disk, and Spotlight
# tries to index all of them, seriously slowing down the tests.
- name: Disable Spotlight Indexing
if: runner.os == 'macOS'
run: |
enabled=$(sudo mdutil -a -s | grep "Indexing enabled" | wc -l)
if [ $enabled -eq 0 ]; then
echo "Spotlight indexing is already disabled"
exit 0
fi
sudo mdutil -a -i off
sudo mdutil -X /
sudo launchctl bootout system /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
# Set up RAM disks to speed up the rest of the job. This action is in
# a separate repository to allow its use before actions/checkout.
- name: Setup RAM Disks
if: runner.os == 'Windows'
uses: coder/setup-ramdisk-action@e1100847ab2d7bcd9d14bcda8f2d1b0f07b36f1b
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
- name: Setup Go Paths
id: go-paths
uses: ./.github/actions/setup-go-paths
- name: Download Go Build Cache
id: download-go-build-cache
uses: ./.github/actions/test-cache/download
with:
key-prefix: test-go-build-${{ runner.os }}-${{ runner.arch }}
cache-path: ${{ steps.go-paths.outputs.cached-dirs }}
- name: Setup Go
uses: ./.github/actions/setup-go
with:
# Runners have Go baked-in and Go will automatically
# download the toolchain configured in go.mod, so we don't
# need to reinstall it. It's faster on Windows runners.
use-preinstalled-go: ${{ runner.os == 'Windows' }}
# Cache is already downloaded above
use-cache: false
- name: Setup Terraform
uses: ./.github/actions/setup-tf
# Sets up the ImDisk toolkit for Windows and creates a RAM disk on drive R:.
- name: Setup ImDisk
if: runner.os == 'Windows'
uses: ./.github/actions/setup-imdisk
- name: Download Test Cache
id: download-cache
uses: ./.github/actions/test-cache/download
with:
key-prefix: test-go-pg-${{ runner.os }}-${{ runner.arch }}
- name: Normalize File and Directory Timestamps
shell: bash
# Normalize file modification timestamps so that go test can use the
# cache from the previous CI run. See https://github.com/golang/go/issues/58571
# for more details.
run: |
find . -type f ! -path ./.git/\*\* | mtimehash
find . -type d ! -path ./.git/\*\* -exec touch -t 200601010000 {} +
- name: Test with PostgreSQL Database
env:
@@ -475,11 +495,86 @@ jobs:
LC_ALL: "en_US.UTF-8"
shell: bash
run: |
# By default Go will use the number of logical CPUs, which
# is a fine default.
PARALLEL_FLAG=""
set -o errexit
set -o pipefail
make test-postgres
if [ "${{ runner.os }}" == "Windows" ]; then
# Create a temp dir on the R: ramdisk drive for Windows. The default
# C: drive is extremely slow: https://github.com/actions/runner-images/issues/8755
mkdir -p "R:/temp/embedded-pg"
go run scripts/embedded-pg/main.go -path "R:/temp/embedded-pg"
elif [ "${{ runner.os }}" == "macOS" ]; then
# Postgres runs faster on a ramdisk on macOS too
mkdir -p /tmp/tmpfs
sudo mount_tmpfs -o noowners -s 8g /tmp/tmpfs
go run scripts/embedded-pg/main.go -path /tmp/tmpfs/embedded-pg
elif [ "${{ runner.os }}" == "Linux" ]; then
make test-postgres-docker
fi
# if macOS, install google-chrome for scaletests
# As another concern, should we really have this kind of external dependency
# requirement on standard CI?
if [ "${{ matrix.os }}" == "macos-latest" ]; then
brew install google-chrome
fi
# macOS will output "The default interactive shell is now zsh"
# intermittently in CI...
if [ "${{ matrix.os }}" == "macos-latest" ]; then
touch ~/.bash_profile && echo "export BASH_SILENCE_DEPRECATION_WARNING=1" >> ~/.bash_profile
fi
if [ "${{ runner.os }}" == "Windows" ]; then
# Our Windows runners have 16 cores.
# On Windows Postgres chokes up when we have 16x16=256 tests
# running in parallel, and dbtestutil.NewDB starts to take more than
# 10s to complete sometimes causing test timeouts. With 16x8=128 tests
# Postgres tends not to choke.
NUM_PARALLEL_PACKAGES=8
NUM_PARALLEL_TESTS=16
elif [ "${{ runner.os }}" == "macOS" ]; then
# Our macOS runners have 8 cores. We set NUM_PARALLEL_TESTS to 16
# because the tests complete faster and Postgres doesn't choke. It seems
# that macOS's tmpfs is faster than the one on Windows.
NUM_PARALLEL_PACKAGES=8
NUM_PARALLEL_TESTS=16
elif [ "${{ runner.os }}" == "Linux" ]; then
# Our Linux runners have 8 cores.
NUM_PARALLEL_PACKAGES=8
NUM_PARALLEL_TESTS=8
fi
# by default, run tests with cache
TESTCOUNT=""
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
# on main, run tests without cache
TESTCOUNT="-count=1"
fi
mkdir -p "$RUNNER_TEMP/sym"
source scripts/normalize_path.sh
# terraform gets installed in a random directory, so we need to normalize
# the path to the terraform binary or a bunch of cached tests will be
# invalidated. See scripts/normalize_path.sh for more details.
normalize_path_with_symlinks "$RUNNER_TEMP/sym" "$(dirname $(which terraform))"
# We rerun failing tests to counteract flakiness coming from Postgres
# choking on macOS and Windows sometimes.
DB=ci gotestsum --rerun-fails=2 --rerun-fails-max-failures=50 \
--format standard-quiet --packages "./..." \
-- -timeout=20m -v -p $NUM_PARALLEL_PACKAGES -parallel=$NUM_PARALLEL_TESTS $TESTCOUNT
- name: Upload Go Build Cache
uses: ./.github/actions/test-cache/upload
with:
cache-key: ${{ steps.download-go-build-cache.outputs.cache-key }}
cache-path: ${{ steps.go-paths.outputs.cached-dirs }}
- name: Upload Test Cache
uses: ./.github/actions/test-cache/upload
with:
cache-key: ${{ steps.download-cache.outputs.cache-key }}
- name: Upload test stats to Datadog
timeout-minutes: 1
@@ -504,7 +599,7 @@ jobs:
timeout-minutes: 25
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -519,13 +614,25 @@ jobs:
- name: Setup Terraform
uses: ./.github/actions/setup-tf
- name: Download Test Cache
id: download-cache
uses: ./.github/actions/test-cache/download
with:
key-prefix: test-go-pg-16-${{ runner.os }}-${{ runner.arch }}
- name: Test with PostgreSQL Database
env:
POSTGRES_VERSION: "16"
TS_DEBUG_DISCO: "true"
TEST_RETRIES: 2
run: |
make test-postgres
- name: Upload Test Cache
uses: ./.github/actions/test-cache/upload
with:
cache-key: ${{ steps.download-cache.outputs.cache-key }}
- name: Upload test stats to Datadog
timeout-minutes: 1
continue-on-error: true
@@ -541,7 +648,7 @@ jobs:
timeout-minutes: 25
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -556,13 +663,24 @@ jobs:
- name: Setup Terraform
uses: ./.github/actions/setup-tf
- name: Download Test Cache
id: download-cache
uses: ./.github/actions/test-cache/download
with:
key-prefix: test-go-race-${{ runner.os }}-${{ runner.arch }}
# We run race tests with reduced parallelism because they use more CPU and we were finding
# instances where tests appear to hang for multiple seconds, resulting in flaky tests when
# short timeouts are used.
# c.f. discussion on https://github.com/coder/coder/pull/15106
- name: Run Tests
run: |
gotestsum --junitfile="gotests.xml" -- -race -parallel 4 -p 4 ./...
gotestsum --junitfile="gotests.xml" --packages="./..." --rerun-fails=2 --rerun-fails-abort-on-data-race -- -race -parallel 4 -p 4
- name: Upload Test Cache
uses: ./.github/actions/test-cache/upload
with:
cache-key: ${{ steps.download-cache.outputs.cache-key }}
- name: Upload test stats to Datadog
timeout-minutes: 1
@@ -579,7 +697,7 @@ jobs:
timeout-minutes: 25
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -594,6 +712,12 @@ jobs:
- name: Setup Terraform
uses: ./.github/actions/setup-tf
- name: Download Test Cache
id: download-cache
uses: ./.github/actions/test-cache/download
with:
key-prefix: test-go-race-pg-${{ runner.os }}-${{ runner.arch }}
# We run race tests with reduced parallelism because they use more CPU and we were finding
# instances where tests appear to hang for multiple seconds, resulting in flaky tests when
# short timeouts are used.
@@ -603,7 +727,12 @@ jobs:
POSTGRES_VERSION: "16"
run: |
make test-postgres-docker
DB=ci gotestsum --junitfile="gotests.xml" -- -race -parallel 4 -p 4 ./...
DB=ci gotestsum --junitfile="gotests.xml" --packages="./..." --rerun-fails=2 --rerun-fails-abort-on-data-race -- -race -parallel 4 -p 4
- name: Upload Test Cache
uses: ./.github/actions/test-cache/upload
with:
cache-key: ${{ steps.download-cache.outputs.cache-key }}
- name: Upload test stats to Datadog
timeout-minutes: 1
@@ -627,7 +756,7 @@ jobs:
timeout-minutes: 20
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -649,11 +778,11 @@ jobs:
test-js:
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
needs: changes
if: needs.changes.outputs.ts == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
if: needs.changes.outputs.site == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
timeout-minutes: 20
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -677,15 +806,15 @@ jobs:
variant:
- premium: false
name: test-e2e
- premium: true
name: test-e2e-premium
#- premium: true
# name: test-e2e-premium
# Skip test-e2e on forks as they don't have access to CI secrets
if: (needs.changes.outputs.go == 'true' || needs.changes.outputs.ts == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main') && !(github.event.pull_request.head.repo.fork)
if: (needs.changes.outputs.go == 'true' || needs.changes.outputs.site == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main') && !(github.event.pull_request.head.repo.fork)
timeout-minutes: 20
name: ${{ matrix.variant.name }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -720,6 +849,7 @@ jobs:
if: ${{ !matrix.variant.premium }}
env:
DEBUG: pw:api
CODER_E2E_TEST_RETRIES: 2
working-directory: site
# Run all of the tests with a premium license
@@ -729,11 +859,12 @@ jobs:
DEBUG: pw:api
CODER_E2E_LICENSE: ${{ secrets.CODER_E2E_LICENSE }}
CODER_E2E_REQUIRE_PREMIUM_TESTS: "1"
CODER_E2E_TEST_RETRIES: 2
working-directory: site
- name: Upload Playwright Failed Tests
if: always() && github.actor != 'dependabot[bot]' && runner.os == 'Linux' && !github.event.pull_request.head.repo.fork
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: failed-test-videos${{ matrix.variant.premium && '-premium' || '' }}
path: ./site/test-results/**/*.webm
@@ -741,29 +872,32 @@ jobs:
- name: Upload pprof dumps
if: always() && github.actor != 'dependabot[bot]' && runner.os == 'Linux' && !github.event.pull_request.head.repo.fork
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: debug-pprof-dumps${{ matrix.variant.premium && '-premium' || '' }}
path: ./site/test-results/**/debug-pprof-*.txt
retention-days: 7
# Reference guide:
# https://www.chromatic.com/docs/turbosnap-best-practices/#run-with-caution-when-using-the-pull_request-event
chromatic:
# REMARK: this is only used to build storybook and deploy it to Chromatic.
runs-on: ubuntu-latest
needs: changes
if: needs.changes.outputs.ts == 'true' || needs.changes.outputs.ci == 'true'
if: needs.changes.outputs.site == 'true' || needs.changes.outputs.ci == 'true'
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# Required by Chromatic for build-over-build history, otherwise we
# only get 1 commit on shallow checkout.
# 👇 Ensures Chromatic can read your full git history
fetch-depth: 0
# 👇 Tells the checkout which commit hash to reference
ref: ${{ github.event.pull_request.head.ref }}
- name: Setup Node
uses: ./.github/actions/setup-node
@@ -773,7 +907,7 @@ jobs:
# the check to pass. This is desired in PRs, but not in mainline.
- name: Publish to Chromatic (non-mainline)
if: github.ref != 'refs/heads/main' && github.repository_owner == 'coder'
uses: chromaui/action@30b6228aa809059d46219e0f556752e8672a7e26 # v11.11.0
uses: chromaui/action@d7afd50124cf4f337bcd943e7f45cfa85a5e4476 # v12.0.0
env:
NODE_OPTIONS: "--max_old_space_size=4096"
STORYBOOK: true
@@ -788,6 +922,7 @@ jobs:
projectToken: 695c25b6cb65
workingDir: "./site"
storybookBaseDir: "./site"
storybookConfigDir: "./site/.storybook"
# Prevent excessive build runs on minor version changes
skip: "@(renovate/**|dependabot/**)"
# Run TurboSnap to trace file dependencies to related stories
@@ -804,7 +939,7 @@ jobs:
# infinitely "in progress" in mainline unless we re-review each build.
- name: Publish to Chromatic (mainline)
if: github.ref == 'refs/heads/main' && github.repository_owner == 'coder'
uses: chromaui/action@30b6228aa809059d46219e0f556752e8672a7e26 # v11.11.0
uses: chromaui/action@d7afd50124cf4f337bcd943e7f45cfa85a5e4476 # v12.0.0
env:
NODE_OPTIONS: "--max_old_space_size=4096"
STORYBOOK: true
@@ -817,6 +952,7 @@ jobs:
projectToken: 695c25b6cb65
workingDir: "./site"
storybookBaseDir: "./site"
storybookConfigDir: "./site/.storybook"
# Run TurboSnap to trace file dependencies to related stories
# and tell chromatic to only take snapshots of relevant stories
onlyChanged: true
@@ -831,7 +967,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -860,12 +996,7 @@ jobs:
uses: ./.github/actions/setup-go
- name: Install go tools
run: |
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30
go install storj.io/drpc/cmd/protoc-gen-go-drpc@v0.0.34
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/mikefarah/yq/v4@v4.44.3
go install go.uber.org/mock/mockgen@v0.5.0
uses: ./.github/actions/setup-go-tools
- name: Setup sqlc
uses: ./.github/actions/setup-sqlc
@@ -905,7 +1036,7 @@ jobs:
if: always()
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -956,7 +1087,7 @@ jobs:
- name: Switch XCode Version
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
xcode-version: "16.0.0"
xcode-version: "16.1.0"
- name: Setup Go
uses: ./.github/actions/setup-go
@@ -1000,7 +1131,7 @@ jobs:
- name: Upload build artifacts
if: ${{ github.repository_owner == 'coder' && github.ref == 'refs/heads/main' }}
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dylibs
path: |
@@ -1024,14 +1155,18 @@ jobs:
# Necessary to push docker images to ghcr.io.
packages: write
# Necessary for GCP authentication (https://github.com/google-github-actions/setup-gcloud#usage)
# Also necessary for keyless cosign (https://docs.sigstore.dev/cosign/signing/overview/)
# And for GitHub Actions attestation
id-token: write
# Required for GitHub Actions attestation
attestations: write
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
outputs:
IMAGE: ghcr.io/coder/coder-preview:${{ steps.build-docker.outputs.tag }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -1041,7 +1176,7 @@ jobs:
fetch-depth: 0
- name: GHCR Login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -1055,7 +1190,7 @@ jobs:
# Necessary for signing Windows binaries.
- name: Setup Java
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: "zulu"
java-version: "11.0"
@@ -1069,6 +1204,12 @@ jobs:
- name: Install zstd
run: sudo apt-get install -y zstd
- name: Install cosign
uses: ./.github/actions/install-cosign
- name: Install syft
uses: ./.github/actions/install-syft
- name: Setup Windows EV Signing Certificate
run: |
set -euo pipefail
@@ -1082,7 +1223,7 @@ jobs:
# Setup GCloud for signing Windows binaries.
- name: Authenticate to Google Cloud
id: gcloud_auth
uses: google-github-actions/auth@71f986410dfbc7added4569d411d040a91dc6935 # v2.1.8
uses: google-github-actions/auth@ba79af03959ebeac9769e648f473a284504d9193 # v2.1.10
with:
workload_identity_provider: ${{ secrets.GCP_CODE_SIGNING_WORKLOAD_ID_PROVIDER }}
service_account: ${{ secrets.GCP_CODE_SIGNING_SERVICE_ACCOUNT }}
@@ -1092,7 +1233,7 @@ jobs:
uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a # v2.1.4
- name: Download dylibs
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dylibs
path: ./build
@@ -1123,6 +1264,8 @@ jobs:
# do (see above).
CODER_SIGN_WINDOWS: "1"
CODER_WINDOWS_RESOURCES: "1"
CODER_SIGN_GPG: "1"
CODER_GPG_RELEASE_KEY_BASE64: ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
EV_KEY: ${{ secrets.EV_KEY }}
EV_KEYSTORE: ${{ secrets.EV_KEYSTORE }}
EV_TSA_URL: ${{ secrets.EV_TSA_URL }}
@@ -1170,6 +1313,166 @@ jobs:
done
fi
- name: SBOM Generation and Attestation
if: github.ref == 'refs/heads/main'
continue-on-error: true
env:
COSIGN_EXPERIMENTAL: 1
run: |
set -euxo pipefail
# Define image base and tags
IMAGE_BASE="ghcr.io/coder/coder-preview"
TAGS=("${{ steps.build-docker.outputs.tag }}" "main" "latest")
# Generate and attest SBOM for each tag
for tag in "${TAGS[@]}"; do
IMAGE="${IMAGE_BASE}:${tag}"
SBOM_FILE="coder_sbom_${tag//[:\/]/_}.spdx.json"
echo "Generating SBOM for image: ${IMAGE}"
syft "${IMAGE}" -o spdx-json > "${SBOM_FILE}"
echo "Attesting SBOM to image: ${IMAGE}"
cosign clean --force=true "${IMAGE}"
cosign attest --type spdxjson \
--predicate "${SBOM_FILE}" \
--yes \
"${IMAGE}"
done
# GitHub attestation provides SLSA provenance for the Docker images, establishing a verifiable
# record that these images were built in GitHub Actions with specific inputs and environment.
# This complements our existing cosign attestations which focus on SBOMs.
#
# We attest each tag separately to ensure all tags have proper provenance records.
# TODO: Consider refactoring these steps to use a matrix strategy or composite action to reduce duplication
# while maintaining the required functionality for each tag.
- name: GitHub Attestation for Docker image
id: attest_main
if: github.ref == 'refs/heads/main'
continue-on-error: true
uses: actions/attest@afd638254319277bb3d7f0a234478733e2e46a73 # v2.3.0
with:
subject-name: "ghcr.io/coder/coder-preview:main"
predicate-type: "https://slsa.dev/provenance/v1"
predicate: |
{
"buildType": "https://github.com/actions/runner-images/",
"builder": {
"id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
"invocation": {
"configSource": {
"uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
"digest": {
"sha1": "${{ github.sha }}"
},
"entryPoint": ".github/workflows/ci.yaml"
},
"environment": {
"github_workflow": "${{ github.workflow }}",
"github_run_id": "${{ github.run_id }}"
}
},
"metadata": {
"buildInvocationID": "${{ github.run_id }}",
"completeness": {
"environment": true,
"materials": true
}
}
}
push-to-registry: true
- name: GitHub Attestation for Docker image (latest tag)
id: attest_latest
if: github.ref == 'refs/heads/main'
continue-on-error: true
uses: actions/attest@afd638254319277bb3d7f0a234478733e2e46a73 # v2.3.0
with:
subject-name: "ghcr.io/coder/coder-preview:latest"
predicate-type: "https://slsa.dev/provenance/v1"
predicate: |
{
"buildType": "https://github.com/actions/runner-images/",
"builder": {
"id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
"invocation": {
"configSource": {
"uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
"digest": {
"sha1": "${{ github.sha }}"
},
"entryPoint": ".github/workflows/ci.yaml"
},
"environment": {
"github_workflow": "${{ github.workflow }}",
"github_run_id": "${{ github.run_id }}"
}
},
"metadata": {
"buildInvocationID": "${{ github.run_id }}",
"completeness": {
"environment": true,
"materials": true
}
}
}
push-to-registry: true
- name: GitHub Attestation for version-specific Docker image
id: attest_version
if: github.ref == 'refs/heads/main'
continue-on-error: true
uses: actions/attest@afd638254319277bb3d7f0a234478733e2e46a73 # v2.3.0
with:
subject-name: "ghcr.io/coder/coder-preview:${{ steps.build-docker.outputs.tag }}"
predicate-type: "https://slsa.dev/provenance/v1"
predicate: |
{
"buildType": "https://github.com/actions/runner-images/",
"builder": {
"id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
"invocation": {
"configSource": {
"uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
"digest": {
"sha1": "${{ github.sha }}"
},
"entryPoint": ".github/workflows/ci.yaml"
},
"environment": {
"github_workflow": "${{ github.workflow }}",
"github_run_id": "${{ github.run_id }}"
}
},
"metadata": {
"buildInvocationID": "${{ github.run_id }}",
"completeness": {
"environment": true,
"materials": true
}
}
}
push-to-registry: true
# Report attestation failures but don't fail the workflow
- name: Check attestation status
if: github.ref == 'refs/heads/main'
run: |
if [[ "${{ steps.attest_main.outcome }}" == "failure" ]]; then
echo "::warning::GitHub attestation for main tag failed"
fi
if [[ "${{ steps.attest_latest.outcome }}" == "failure" ]]; then
echo "::warning::GitHub attestation for latest tag failed"
fi
if [[ "${{ steps.attest_version.outcome }}" == "failure" ]]; then
echo "::warning::GitHub attestation for version-specific tag failed"
fi
- name: Prune old images
if: github.ref == 'refs/heads/main'
uses: vlaurin/action-ghcr-prune@0cf7d39f88546edd31965acba78cdcb0be14d641 # v0.6.0
@@ -1187,7 +1490,7 @@ jobs:
- name: Upload build artifacts
if: github.ref == 'refs/heads/main'
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coder
path: |
@@ -1211,7 +1514,7 @@ jobs:
id-token: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -1221,7 +1524,7 @@ jobs:
fetch-depth: 0
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@71f986410dfbc7added4569d411d040a91dc6935 # v2.1.8
uses: google-github-actions/auth@ba79af03959ebeac9769e648f473a284504d9193 # v2.1.10
with:
workload_identity_provider: projects/573722524737/locations/global/workloadIdentityPools/github/providers/github
service_account: coder-ci@coder-dogfood.iam.gserviceaccount.com
@@ -1236,7 +1539,7 @@ jobs:
version: "2.5.1"
- name: Get Cluster Credentials
uses: google-github-actions/get-gke-credentials@7a108e64ed8546fe38316b4086e91da13f4785e1 # v2.3.1
uses: google-github-actions/get-gke-credentials@d0cee45012069b163a631894b98904a9e6723729 # v2.3.3
with:
cluster_name: dogfood-v2
location: us-central1-a
@@ -1266,6 +1569,8 @@ jobs:
kubectl --namespace coder rollout status deployment/coder
kubectl --namespace coder rollout restart deployment/coder-provisioner
kubectl --namespace coder rollout status deployment/coder-provisioner
kubectl --namespace coder rollout restart deployment/coder-provisioner-tagged
kubectl --namespace coder rollout status deployment/coder-provisioner-tagged
deploy-wsproxies:
runs-on: ubuntu-latest
@@ -1273,7 +1578,7 @@ jobs:
if: github.ref == 'refs/heads/main' && !github.event.pull_request.head.repo.fork
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -1308,7 +1613,7 @@ jobs:
if: needs.changes.outputs.db == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@d7267f607e9d3fb96fc2fbe83e0af444713e90b7 # v2.3.0
uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
+2 -2
View File
@@ -38,7 +38,7 @@ jobs:
if: github.repository_owner == 'coder'
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -46,7 +46,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Docker login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
- name: Setup Node
uses: ./.github/actions/setup-node
- uses: tj-actions/changed-files@dcc7a0cba800f454d79fff4b993e8c3555bcc0a8 # v45.0.7
- uses: tj-actions/changed-files@3981e4f74104e7a4c67a835e1e5dd5d9eb0f0a57 # v45.0.7
id: changed-files
with:
files: |
+38 -13
View File
@@ -27,7 +27,7 @@ jobs:
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || 'ubuntu-latest' }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -35,11 +35,30 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Nix
uses: DeterminateSystems/nix-installer-action@e50d5f73bfe71c2dd0aa4218de8f4afa59f8f81d # v16
uses: nixbuild/nix-quick-install-action@5bb6a3b3abe66fd09bbf250dce8ada94f856a703 # v30
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
with:
# restore and save a cache using this key
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
# if there's no cache hit, restore a cache by this prefix
restore-prefixes-first-match: nix-${{ runner.os }}-
# collect garbage until Nix store size (in bytes) is at most this number
# before trying to save a new cache
# 1G = 1073741824
gc-max-store-size-linux: 5G
# do purge caches
purge: true
# purge all versions of the cache
purge-prefixes: nix-${{ runner.os }}-
# created more than this number of seconds ago relative to the start of the `Post Restore` phase
purge-created: 0
# except the version with the `primary-key`, if it exists
purge-primary-key: never
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@6871f53176ad61624f978536bbf089c574dc19a2 # v8.0.1
uses: tj-actions/branch-names@dde14ac574a8b9b1cedc59a1cf312788af43d8d8 # v8.2.1
- name: "Branch name to Docker tag name"
id: docker-tag-name
@@ -53,11 +72,11 @@ jobs:
uses: depot/setup-action@b0b1ea4f69e92ebf5dea3f8713a1b0c37b2126a5 # v1.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Login to DockerHub
if: github.ref == 'refs/heads/main'
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
@@ -68,7 +87,7 @@ jobs:
project: b4q6ltmpzh
token: ${{ secrets.DEPOT_TOKEN }}
buildx-fallback: true
context: "{{defaultContext}}:dogfood/contents"
context: "{{defaultContext}}:dogfood/coder"
pull: true
save: true
push: ${{ github.ref == 'refs/heads/main' }}
@@ -95,7 +114,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -106,19 +125,25 @@ jobs:
uses: ./.github/actions/setup-tf
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@71f986410dfbc7added4569d411d040a91dc6935 # v2.1.8
uses: google-github-actions/auth@ba79af03959ebeac9769e648f473a284504d9193 # v2.1.10
with:
workload_identity_provider: projects/573722524737/locations/global/workloadIdentityPools/github/providers/github
service_account: coder-ci@coder-dogfood.iam.gserviceaccount.com
- name: Terraform init and validate
run: |
cd dogfood
terraform init -upgrade
pushd dogfood/
terraform init
terraform validate
cd contents
terraform init -upgrade
popd
pushd dogfood/coder
terraform init
terraform validate
popd
pushd dogfood/coder-envbuilder
terraform init
terraform validate
popd
- name: Get short commit SHA
if: github.ref == 'refs/heads/main'
@@ -142,6 +167,6 @@ jobs:
# Template source & details
TF_VAR_CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }}
TF_VAR_CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }}
TF_VAR_CODER_TEMPLATE_DIR: ./contents
TF_VAR_CODER_TEMPLATE_DIR: ./coder
TF_VAR_CODER_TEMPLATE_MESSAGE: ${{ steps.message.outputs.pr_title }}
TF_LOG: info
-141
View File
@@ -1,141 +0,0 @@
# The nightly-gauntlet runs tests that are either too flaky or too slow to block
# every PR.
name: nightly-gauntlet
on:
schedule:
# Every day at 4AM
- cron: "0 4 * * 1-5"
workflow_dispatch:
permissions:
contents: read
jobs:
test-go-pg:
runs-on: ${{ matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'depot-macos-latest' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'windows-latest-16-cores' || matrix.os }}
if: github.ref == 'refs/heads/main'
# This timeout must be greater than the timeout set by `go test` in
# `make test-postgres` to ensure we receive a trace of running
# goroutines. Setting this to the timeout +5m should work quite well
# even if some of the preceding steps are slow.
timeout-minutes: 25
strategy:
matrix:
os:
- macos-latest
- windows-2022
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 1
- name: Setup Go
uses: ./.github/actions/setup-go
- name: Setup Terraform
uses: ./.github/actions/setup-tf
# Sets up the ImDisk toolkit for Windows and creates a RAM disk on drive R:.
- name: Setup ImDisk
if: runner.os == 'Windows'
uses: ./.github/actions/setup-imdisk
- name: Test with PostgreSQL Database
env:
POSTGRES_VERSION: "13"
TS_DEBUG_DISCO: "true"
LC_CTYPE: "en_US.UTF-8"
LC_ALL: "en_US.UTF-8"
shell: bash
run: |
# if macOS, install google-chrome for scaletests
# As another concern, should we really have this kind of external dependency
# requirement on standard CI?
if [ "${{ matrix.os }}" == "macos-latest" ]; then
brew install google-chrome
fi
# By default Go will use the number of logical CPUs, which
# is a fine default.
PARALLEL_FLAG=""
# macOS will output "The default interactive shell is now zsh"
# intermittently in CI...
if [ "${{ matrix.os }}" == "macos-latest" ]; then
touch ~/.bash_profile && echo "export BASH_SILENCE_DEPRECATION_WARNING=1" >> ~/.bash_profile
fi
if [ "${{ runner.os }}" == "Windows" ]; then
# Create a temp dir on the R: ramdisk drive for Windows. The default
# C: drive is extremely slow: https://github.com/actions/runner-images/issues/8755
mkdir -p "R:/temp/embedded-pg"
go run scripts/embedded-pg/main.go -path "R:/temp/embedded-pg"
else
go run scripts/embedded-pg/main.go
fi
# Reduce test parallelism, mirroring what we do for race tests.
# We'd been encountering issues with timing related flakes, and
# this seems to help.
DB=ci gotestsum --format standard-quiet -- -v -short -count=1 -parallel 4 -p 4 ./...
- name: Upload test stats to Datadog
timeout-minutes: 1
continue-on-error: true
uses: ./.github/actions/upload-datadog
if: success() || failure()
with:
api-key: ${{ secrets.DATADOG_API_KEY }}
notify-slack-on-failure:
needs:
- test-go-pg
runs-on: ubuntu-latest
if: failure() && github.ref == 'refs/heads/main'
steps:
- name: Send Slack notification
run: |
curl -X POST -H 'Content-type: application/json' \
--data '{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "❌ Nightly gauntlet failed",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Workflow:*\n${{ github.workflow }}"
},
{
"type": "mrkdwn",
"text": "*Committer:*\n${{ github.actor }}"
},
{
"type": "mrkdwn",
"text": "*Commit:*\n${{ github.sha }}"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*View failure:* <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Click here>"
}
}
]
}' ${{ secrets.CI_FAILURE_SLACK_WEBHOOK }}
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
packages: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
+6 -6
View File
@@ -39,7 +39,7 @@ jobs:
PR_OPEN: ${{ steps.check_pr.outputs.pr_open }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -74,7 +74,7 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -174,7 +174,7 @@ jobs:
pull-requests: write # needed for commenting on PRs
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -218,7 +218,7 @@ jobs:
CODER_IMAGE_TAG: ${{ needs.get_info.outputs.CODER_IMAGE_TAG }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -237,7 +237,7 @@ jobs:
uses: ./.github/actions/setup-sqlc
- name: GHCR Login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -276,7 +276,7 @@ jobs:
PR_HOSTNAME: "pr${{ needs.get_info.outputs.PR_NUMBER }}.${{ secrets.PR_DEPLOYMENTS_DOMAIN }}"
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
+260 -19
View File
@@ -60,7 +60,7 @@ jobs:
- name: Switch XCode Version
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
xcode-version: "16.0.0"
xcode-version: "16.1.0"
- name: Setup Go
uses: ./.github/actions/setup-go
@@ -101,7 +101,7 @@ jobs:
AC_CERTIFICATE_PASSWORD_FILE: /tmp/apple_cert_password.txt
- name: Upload build artifacts
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dylibs
path: |
@@ -122,7 +122,11 @@ jobs:
# Necessary to push docker images to ghcr.io.
packages: write
# Necessary for GCP authentication (https://github.com/google-github-actions/setup-gcloud#usage)
# Also necessary for keyless cosign (https://docs.sigstore.dev/cosign/signing/overview/)
# And for GitHub Actions attestation
id-token: write
# Required for GitHub Actions attestation
attestations: write
env:
# Necessary for Docker manifest
DOCKER_CLI_EXPERIMENTAL: "enabled"
@@ -130,7 +134,7 @@ jobs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -204,7 +208,7 @@ jobs:
cat "$CODER_RELEASE_NOTES_FILE"
- name: Docker Login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -218,7 +222,7 @@ jobs:
# Necessary for signing Windows binaries.
- name: Setup Java
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
distribution: "zulu"
java-version: "11.0"
@@ -246,6 +250,12 @@ jobs:
apple-codesign-0.22.0-x86_64-unknown-linux-musl/rcodesign
rm /tmp/rcodesign.tar.gz
- name: Install cosign
uses: ./.github/actions/install-cosign
- name: Install syft
uses: ./.github/actions/install-syft
- name: Setup Apple Developer certificate and API key
run: |
set -euo pipefail
@@ -276,7 +286,7 @@ jobs:
# Setup GCloud for signing Windows binaries.
- name: Authenticate to Google Cloud
id: gcloud_auth
uses: google-github-actions/auth@71f986410dfbc7added4569d411d040a91dc6935 # v2.1.8
uses: google-github-actions/auth@ba79af03959ebeac9769e648f473a284504d9193 # v2.1.10
with:
workload_identity_provider: ${{ secrets.GCP_CODE_SIGNING_WORKLOAD_ID_PROVIDER }}
service_account: ${{ secrets.GCP_CODE_SIGNING_SERVICE_ACCOUNT }}
@@ -286,7 +296,7 @@ jobs:
uses: google-github-actions/setup-gcloud@77e7a554d41e2ee56fc945c52dfd3f33d12def9a # v2.1.4
- name: Download dylibs
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dylibs
path: ./build
@@ -313,6 +323,8 @@ jobs:
env:
CODER_SIGN_WINDOWS: "1"
CODER_SIGN_DARWIN: "1"
CODER_SIGN_GPG: "1"
CODER_GPG_RELEASE_KEY_BASE64: ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
CODER_WINDOWS_RESOURCES: "1"
AC_CERTIFICATE_FILE: /tmp/apple_cert.p12
AC_CERTIFICATE_PASSWORD_FILE: /tmp/apple_cert_password.txt
@@ -361,6 +373,7 @@ jobs:
file: scripts/Dockerfile.base
platforms: linux/amd64,linux/arm64,linux/arm/v7
provenance: true
sbom: true
pull: true
no-cache: true
push: true
@@ -397,7 +410,52 @@ jobs:
echo "$manifests" | grep -q linux/arm64
echo "$manifests" | grep -q linux/arm/v7
# GitHub attestation provides SLSA provenance for Docker images, establishing a verifiable
# record that these images were built in GitHub Actions with specific inputs and environment.
# This complements our existing cosign attestations (which focus on SBOMs) by adding
# GitHub-specific build provenance to enhance our supply chain security.
#
# TODO: Consider refactoring these attestation steps to use a matrix strategy or composite action
# to reduce duplication while maintaining the required functionality for each distinct image tag.
- name: GitHub Attestation for Base Docker image
id: attest_base
if: ${{ !inputs.dry_run && steps.image-base-tag.outputs.tag != '' }}
continue-on-error: true
uses: actions/attest@afd638254319277bb3d7f0a234478733e2e46a73 # v2.3.0
with:
subject-name: ${{ steps.image-base-tag.outputs.tag }}
predicate-type: "https://slsa.dev/provenance/v1"
predicate: |
{
"buildType": "https://github.com/actions/runner-images/",
"builder": {
"id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
"invocation": {
"configSource": {
"uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
"digest": {
"sha1": "${{ github.sha }}"
},
"entryPoint": ".github/workflows/release.yaml"
},
"environment": {
"github_workflow": "${{ github.workflow }}",
"github_run_id": "${{ github.run_id }}"
}
},
"metadata": {
"buildInvocationID": "${{ github.run_id }}",
"completeness": {
"environment": true,
"materials": true
}
}
}
push-to-registry: true
- name: Build Linux Docker images
id: build_docker
run: |
set -euxo pipefail
@@ -416,18 +474,158 @@ jobs:
# being pushed so will automatically push them.
make push/build/coder_"$version"_linux.tag
# Save multiarch image tag for attestation
multiarch_image="$(./scripts/image_tag.sh)"
echo "multiarch_image=${multiarch_image}" >> $GITHUB_OUTPUT
# For debugging, print all docker image tags
docker images
# if the current version is equal to the highest (according to semver)
# version in the repo, also create a multi-arch image as ":latest" and
# push it
created_latest_tag=false
if [[ "$(git tag | grep '^v' | grep -vE '(rc|dev|-|\+|\/)' | sort -r --version-sort | head -n1)" == "v$(./scripts/version.sh)" ]]; then
./scripts/build_docker_multiarch.sh \
--push \
--target "$(./scripts/image_tag.sh --version latest)" \
$(cat build/coder_"$version"_linux_{amd64,arm64,armv7}.tag)
created_latest_tag=true
echo "created_latest_tag=true" >> $GITHUB_OUTPUT
else
echo "created_latest_tag=false" >> $GITHUB_OUTPUT
fi
env:
CODER_BASE_IMAGE_TAG: ${{ steps.image-base-tag.outputs.tag }}
- name: SBOM Generation and Attestation
if: ${{ !inputs.dry_run }}
env:
COSIGN_EXPERIMENTAL: "1"
run: |
set -euxo pipefail
# Generate SBOM for multi-arch image with version in filename
echo "Generating SBOM for multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
syft "${{ steps.build_docker.outputs.multiarch_image }}" -o spdx-json > coder_${{ steps.version.outputs.version }}_sbom.spdx.json
# Attest SBOM to multi-arch image
echo "Attesting SBOM to multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
cosign clean --force=true "${{ steps.build_docker.outputs.multiarch_image }}"
cosign attest --type spdxjson \
--predicate coder_${{ steps.version.outputs.version }}_sbom.spdx.json \
--yes \
"${{ steps.build_docker.outputs.multiarch_image }}"
# If latest tag was created, also attest it
if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
latest_tag="$(./scripts/image_tag.sh --version latest)"
echo "Generating SBOM for latest image: ${latest_tag}"
syft "${latest_tag}" -o spdx-json > coder_latest_sbom.spdx.json
echo "Attesting SBOM to latest image: ${latest_tag}"
cosign clean --force=true "${latest_tag}"
cosign attest --type spdxjson \
--predicate coder_latest_sbom.spdx.json \
--yes \
"${latest_tag}"
fi
- name: GitHub Attestation for Docker image
id: attest_main
if: ${{ !inputs.dry_run }}
continue-on-error: true
uses: actions/attest@afd638254319277bb3d7f0a234478733e2e46a73 # v2.3.0
with:
subject-name: ${{ steps.build_docker.outputs.multiarch_image }}
predicate-type: "https://slsa.dev/provenance/v1"
predicate: |
{
"buildType": "https://github.com/actions/runner-images/",
"builder": {
"id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
"invocation": {
"configSource": {
"uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
"digest": {
"sha1": "${{ github.sha }}"
},
"entryPoint": ".github/workflows/release.yaml"
},
"environment": {
"github_workflow": "${{ github.workflow }}",
"github_run_id": "${{ github.run_id }}"
}
},
"metadata": {
"buildInvocationID": "${{ github.run_id }}",
"completeness": {
"environment": true,
"materials": true
}
}
}
push-to-registry: true
# Get the latest tag name for attestation
- name: Get latest tag name
id: latest_tag
if: ${{ !inputs.dry_run && steps.build_docker.outputs.created_latest_tag == 'true' }}
run: echo "tag=$(./scripts/image_tag.sh --version latest)" >> $GITHUB_OUTPUT
# If this is the highest version according to semver, also attest the "latest" tag
- name: GitHub Attestation for "latest" Docker image
id: attest_latest
if: ${{ !inputs.dry_run && steps.build_docker.outputs.created_latest_tag == 'true' }}
continue-on-error: true
uses: actions/attest@afd638254319277bb3d7f0a234478733e2e46a73 # v2.3.0
with:
subject-name: ${{ steps.latest_tag.outputs.tag }}
predicate-type: "https://slsa.dev/provenance/v1"
predicate: |
{
"buildType": "https://github.com/actions/runner-images/",
"builder": {
"id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
"invocation": {
"configSource": {
"uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
"digest": {
"sha1": "${{ github.sha }}"
},
"entryPoint": ".github/workflows/release.yaml"
},
"environment": {
"github_workflow": "${{ github.workflow }}",
"github_run_id": "${{ github.run_id }}"
}
},
"metadata": {
"buildInvocationID": "${{ github.run_id }}",
"completeness": {
"environment": true,
"materials": true
}
}
}
push-to-registry: true
# Report attestation failures but don't fail the workflow
- name: Check attestation status
if: ${{ !inputs.dry_run }}
run: |
if [[ "${{ steps.attest_base.outcome }}" == "failure" && "${{ steps.attest_base.conclusion }}" != "skipped" ]]; then
echo "::warning::GitHub attestation for base image failed"
fi
if [[ "${{ steps.attest_main.outcome }}" == "failure" ]]; then
echo "::warning::GitHub attestation for main image failed"
fi
if [[ "${{ steps.attest_latest.outcome }}" == "failure" && "${{ steps.attest_latest.conclusion }}" != "skipped" ]]; then
echo "::warning::GitHub attestation for latest image failed"
fi
- name: Generate offline docs
run: |
version="$(./scripts/version.sh)"
@@ -436,6 +634,29 @@ jobs:
- name: ls build
run: ls -lh build
- name: Publish Coder CLI binaries and detached signatures to GCS
if: ${{ !inputs.dry_run && github.ref == 'refs/heads/main' && github.repository_owner == 'coder'}}
run: |
set -euxo pipefail
version="$(./scripts/version.sh)"
binaries=(
"coder-darwin-amd64"
"coder-darwin-arm64"
"coder-linux-amd64"
"coder-linux-arm64"
"coder-linux-armv7"
"coder-windows-amd64.exe"
"coder-windows-arm64.exe"
)
for binary in "${binaries[@]}"; do
detached_signature="${binary}.asc"
gcloud storage cp "./site/out/bin/${binary}" "gs://releases.coder.com/coder-cli/${version}/${binary}"
gcloud storage cp "./site/out/bin/${detached_signature}" "gs://releases.coder.com/coder-cli/${version}/${detached_signature}"
done
- name: Publish release
run: |
set -euo pipefail
@@ -449,22 +670,33 @@ jobs:
fi
declare -p publish_args
# Build the list of files to publish
files=(
./build/*_installer.exe
./build/*.zip
./build/*.tar.gz
./build/*.tgz
./build/*.apk
./build/*.deb
./build/*.rpm
./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
)
# Only include the latest SBOM file if it was created
if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
files+=(./coder_latest_sbom.spdx.json)
fi
./scripts/release/publish.sh \
"${publish_args[@]}" \
--release-notes-file "$CODER_RELEASE_NOTES_FILE" \
./build/*_installer.exe \
./build/*.zip \
./build/*.tar.gz \
./build/*.tgz \
./build/*.apk \
./build/*.deb \
./build/*.rpm
"${files[@]}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CODER_GPG_RELEASE_KEY_BASE64: ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@71f986410dfbc7added4569d411d040a91dc6935 # v2.1.8
uses: google-github-actions/auth@ba79af03959ebeac9769e648f473a284504d9193 # v2.1.10
with:
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_ID_PROVIDER }}
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
@@ -489,7 +721,7 @@ jobs:
- name: Upload artifacts to actions (if dry-run)
if: ${{ inputs.dry_run }}
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: release-artifacts
path: |
@@ -500,6 +732,15 @@ jobs:
./build/*.apk
./build/*.deb
./build/*.rpm
./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
retention-days: 7
- name: Upload latest sbom artifact to actions (if dry-run)
if: inputs.dry_run && steps.build_docker.outputs.created_latest_tag == 'true'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: latest-sbom-artifact
path: ./coder_latest_sbom.spdx.json
retention-days: 7
- name: Send repository-dispatch event
@@ -521,7 +762,7 @@ jobs:
# TODO: skip this if it's not a new release (i.e. a backport). This is
# fine right now because it just makes a PR that we can close.
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -597,7 +838,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -687,7 +928,7 @@ jobs:
if: ${{ !inputs.dry_run }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
+3 -3
View File
@@ -20,7 +20,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -39,7 +39,7 @@ jobs:
# Upload the results as artifacts.
- name: "Upload artifact"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@@ -47,6 +47,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
sarif_file: results.sarif
+14 -8
View File
@@ -27,7 +27,7 @@ jobs:
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -38,7 +38,7 @@ jobs:
uses: ./.github/actions/setup-go
- name: Initialize CodeQL
uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: go, javascript
@@ -48,7 +48,7 @@ jobs:
rm Makefile
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
- name: Send Slack notification on failure
if: ${{ failure() }}
@@ -67,7 +67,7 @@ jobs:
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -85,6 +85,12 @@ jobs:
- name: Setup sqlc
uses: ./.github/actions/setup-sqlc
- name: Install cosign
uses: ./.github/actions/install-cosign
- name: Install syft
uses: ./.github/actions/install-syft
- name: Install yq
run: go run github.com/mikefarah/yq/v4@v4.44.3
- name: Install mockgen
@@ -99,7 +105,7 @@ jobs:
# version in the comments will differ. This is also defined in
# ci.yaml.
set -euxo pipefail
cd dogfood/contents
cd dogfood/coder
mkdir -p /usr/local/bin
mkdir -p /usr/local/include
@@ -136,7 +142,7 @@ jobs:
echo "image=$(cat "$image_job")" >> $GITHUB_OUTPUT
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@18f2510ee396bbf400402947b394f2dd8c87dbb0
uses: aquasecurity/trivy-action@6c175e9c4083a92bbca2f9724c8a5e33bc2d97a5
with:
image-ref: ${{ steps.build.outputs.image }}
format: sarif
@@ -144,13 +150,13 @@ jobs:
severity: "CRITICAL,HIGH"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
sarif_file: trivy-results.sarif
category: "Trivy"
- name: Upload Trivy scan results as an artifact
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: trivy
path: trivy-results.sarif
+4 -4
View File
@@ -18,7 +18,7 @@ jobs:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -96,14 +96,14 @@ jobs:
contents: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run delete-old-branches-action
uses: beatlabs/delete-old-branches-action@6e94df089372a619c01ae2c2f666bf474f890911 # v0.0.10
uses: beatlabs/delete-old-branches-action@4eeeb8740ff8b3cb310296ddd6b43c3387734588 # v0.0.11
with:
repo_token: ${{ github.token }}
date: "6 months ago"
@@ -118,7 +118,7 @@ jobs:
actions: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
+35
View File
@@ -0,0 +1,35 @@
name: Start Workspace On Issue Creation or Comment
on:
issues:
types: [opened]
issue_comment:
types: [created]
permissions:
issues: write
jobs:
comment:
runs-on: ubuntu-latest
if: >-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@coder')) ||
(github.event_name == 'issues' && contains(github.event.issue.body, '@coder'))
environment: dev.coder.com
timeout-minutes: 5
steps:
- name: Start Coder workspace
uses: coder/start-workspace-action@35a4608cefc7e8cc56573cae7c3b85304575cb72
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
github-username: >-
${{
(github.event_name == 'issue_comment' && github.event.comment.user.login) ||
(github.event_name == 'issues' && github.event.issue.user.login)
}}
coder-url: ${{ secrets.CODER_URL }}
coder-token: ${{ secrets.CODER_TOKEN }}
template-name: ${{ secrets.CODER_TEMPLATE_NAME }}
parameters: |-
AI Prompt: "Use the gh CLI tool to read the details of issue https://github.com/${{ github.repository }}/issues/${{ github.event.issue.number }} and then address it."
Region: us-pittsburgh
+6 -1
View File
@@ -1,3 +1,6 @@
[default]
extend-ignore-identifiers-re = ["gho_.*"]
[default.extend-identifiers]
alog = "alog"
Jetbrains = "JetBrains"
@@ -24,6 +27,7 @@ EDE = "EDE"
HELO = "HELO"
LKE = "LKE"
byt = "byt"
typ = "typ"
[files]
extend-exclude = [
@@ -42,5 +46,6 @@ extend-exclude = [
"site/src/pages/SetupPage/countries.tsx",
"provisioner/terraform/testdata/**",
# notifications' golden files confuse the detector because of quoted-printable encoding
"coderd/notifications/testdata/**"
"coderd/notifications/testdata/**",
"agent/agentcontainers/testdata/devcontainercli/**"
]
+3 -3
View File
@@ -21,7 +21,7 @@ jobs:
pull-requests: write # required to post PR review comments by the action
steps:
- name: Harden Runner
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
with:
egress-policy: audit
@@ -29,14 +29,14 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Check Markdown links
uses: umbrelladocs/action-linkspector@de84085e0f51452a470558693d7d308fbb2fa261 # v1.2.5
uses: umbrelladocs/action-linkspector@a0567ce1c7c13de4a2358587492ed43cab5d0102 # v1.3.4
id: markdown-link-check
# checks all markdown files from /docs including all subfolders
with:
reporter: github-pr-review
config_file: ".github/.linkspector.yml"
fail_on_error: "true"
filter_mode: "nofilter"
filter_mode: "file"
- name: Send Slack notification
if: failure() && github.event_name == 'schedule'
+9 -1
View File
@@ -32,7 +32,8 @@ site/e2e/.auth.json
site/playwright-report/*
site/.swc
# Make target for updating golden files (any dir).
# Make target for updating generated/golden files (any dir).
.gen
.gen-golden
# Build
@@ -49,6 +50,8 @@ site/stats/
*.tfplan
*.lock.hcl
.terraform/
!coderd/testdata/parameters/modules/.terraform/
!provisioner/terraform/testdata/modules-source-caching/.terraform/
**/.coderv2/*
**/__debug_bin
@@ -78,3 +81,8 @@ result
# Zed
.zed_server
# dlv debug binaries for go tests
__debug_bin*
**/.claude/settings.local.json
+12 -29
View File
@@ -24,30 +24,19 @@ linters-settings:
enabled-checks:
# - appendAssign
# - appendCombine
- argOrder
# - assignOp
# - badCall
- badCond
- badLock
- badRegexp
- boolExprSimplify
# - builtinShadow
- builtinShadowDecl
- captLocal
- caseOrder
- codegenComment
# - commentedOutCode
- commentedOutImport
- commentFormatting
- defaultCaseOrder
- deferUnlambda
# - deprecatedComment
# - docStub
- dupArg
- dupBranchBody
- dupCase
- dupImport
- dupSubExpr
# - elseif
- emptyFallthrough
# - emptyStringTest
@@ -56,8 +45,6 @@ linters-settings:
# - exitAfterDefer
# - exposedSyncMutex
# - filepathJoin
- flagDeref
- flagName
- hexLiteral
# - httpNoBody
# - hugeParam
@@ -65,47 +52,36 @@ linters-settings:
# - importShadow
- indexAlloc
- initClause
- mapKey
- methodExprCall
# - nestingReduce
- newDeref
- nilValReturn
# - octalLiteral
- offBy1
# - paramTypeCombine
# - preferStringWriter
# - preferWriteByte
# - ptrToRefParam
# - rangeExprCopy
# - rangeValCopy
- regexpMust
- regexpPattern
# - regexpSimplify
- ruleguard
- singleCaseSwitch
- sloppyLen
# - sloppyReassign
- sloppyTypeAssert
- sortSlice
- sprintfQuotedString
- sqlQuery
# - stringConcatSimplify
# - stringXbytes
# - suspiciousSorting
- switchTrue
- truncateCmp
- typeAssertChain
# - typeDefFirst
- typeSwitchVar
# - typeUnparen
- underef
# - unlabelStmt
# - unlambda
# - unnamedResult
# - unnecessaryBlock
# - unnecessaryDefer
# - unslice
- valSwap
- weakCond
# - whyNoLint
# - wrapperFunc
@@ -188,6 +164,7 @@ linters-settings:
- name: unnecessary-stmt
- name: unreachable-code
- name: unused-parameter
exclude: "**/*_test.go"
- name: unused-receiver
- name: var-declaration
- name: var-naming
@@ -203,6 +180,14 @@ linters-settings:
- G601
issues:
exclude-dirs:
- coderd/database/dbmem
- node_modules
- .git
exclude-files:
- scripts/rules.go
# Rules listed here: https://github.com/securego/gosec#available-rules
exclude-rules:
- path: _test\.go
@@ -214,17 +199,15 @@ issues:
- path: scripts/*
linters:
- exhaustruct
- path: scripts/rules.go
linters:
- ALL
fix: true
max-issues-per-linter: 0
max-same-issues: 0
run:
skip-dirs:
- node_modules
- .git
skip-files:
- scripts/rules.go
timeout: 10m
# Over time, add more and more linters from
+8 -9
View File
@@ -1,14 +1,14 @@
{
// For info about snippets, visit https://code.visualstudio.com/docs/editor/userdefinedsnippets
// https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
"admonition": {
"prefix": "#callout",
"alert": {
"prefix": "#alert",
"body": [
"<blockquote class=\"admonition ${1|caution,important,note,tip,warning|}\">\n",
"${TM_SELECTED_TEXT:${2:add info here}}\n",
"</blockquote>\n"
"> [!${1|CAUTION,IMPORTANT,NOTE,TIP,WARNING|}]",
"> ${TM_SELECTED_TEXT:${2:add info here}}\n"
],
"description": "callout admonition caution info note tip warning"
"description": "callout admonition caution important note tip warning"
},
"fenced code block": {
"prefix": "#codeblock",
@@ -23,9 +23,8 @@
"premium-feature": {
"prefix": "#premium-feature",
"body": [
"<blockquote class=\"info\">\n",
"${1:feature} ${2|is,are|} an Enterprise and Premium feature. [Learn more](https://coder.com/pricing#compare-plans).\n",
"</blockquote>"
"> [!NOTE]\n",
"> ${1:feature} ${2|is,are|} an Enterprise and Premium feature. [Learn more](https://coder.com/pricing#compare-plans).\n"
]
},
"tabs": {
+4 -1
View File
@@ -57,5 +57,8 @@
"[css][html][markdown][yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"typos.config": ".github/workflows/typos.toml"
"typos.config": ".github/workflows/typos.toml",
"[markdown]": {
"editor.defaultFormatter": "DavidAnson.vscode-markdownlint"
}
}
+104
View File
@@ -0,0 +1,104 @@
# Coder Development Guidelines
Read [cursor rules](.cursorrules).
## Build/Test/Lint Commands
### Main Commands
- `make build` or `make build-fat` - Build all "fat" binaries (includes "server" functionality)
- `make build-slim` - Build "slim" binaries
- `make test` - Run Go tests
- `make test RUN=TestFunctionName` or `go test -v ./path/to/package -run TestFunctionName` - Test single
- `make test-postgres` - Run tests with Postgres database
- `make test-race` - Run tests with Go race detector
- `make test-e2e` - Run end-to-end tests
- `make lint` - Run all linters
- `make fmt` - Format all code
- `make gen` - Generates mocks, database queries and other auto-generated files
### Frontend Commands (site directory)
- `pnpm build` - Build frontend
- `pnpm dev` - Run development server
- `pnpm check` - Run code checks
- `pnpm format` - Format frontend code
- `pnpm lint` - Lint frontend code
- `pnpm test` - Run frontend tests
## Code Style Guidelines
### Go
- Follow [Effective Go](https://go.dev/doc/effective_go) and [Go's Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
- Use `gofumpt` for formatting
- Create packages when used during implementation
- Validate abstractions against implementations
### Error Handling
- Use descriptive error messages
- Wrap errors with context
- Propagate errors appropriately
- Use proper error types
- (`xerrors.Errorf("failed to X: %w", err)`)
### Naming
- Use clear, descriptive names
- Abbreviate only when obvious
- Follow Go and TypeScript naming conventions
### Comments
- Document exported functions, types, and non-obvious logic
- Follow JSDoc format for TypeScript
- Use godoc format for Go code
## Commit Style
- Follow [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/)
- Format: `type(scope): message`
- Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
- Keep message titles concise (~70 characters)
- Use imperative, present tense in commit titles
## Database queries
- MUST DO! Any changes to database - adding queries, modifying queries should be done in the `coderd\database\queries\*.sql` files. Use `make gen` to generate necessary changes after.
- MUST DO! Queries are grouped in files relating to context - e.g. `prebuilds.sql`, `users.sql`, `provisionerjobs.sql`.
- After making changes to any `coderd\database\queries\*.sql` files you must run `make gen` to generate respective ORM changes.
## Architecture
### Core Components
- **coderd**: Main API service connecting workspaces, provisioners, and users
- **provisionerd**: Execution context for infrastructure-modifying providers
- **Agents**: Services in remote workspaces providing features like SSH and port forwarding
- **Workspaces**: Cloud resources defined by Terraform
## Sub-modules
### Template System
- Templates define infrastructure for workspaces using Terraform
- Environment variables pass context between Coder and templates
- Official modules extend development environments
### RBAC System
- Permissions defined at site, organization, and user levels
- Object-Action model protects resources
- Built-in roles: owner, member, auditor, templateAdmin
- Permission format: `<sign>?<level>.<object>.<id>.<action>`
### Database
- PostgreSQL 13+ recommended for production
- Migrations managed with `migrate`
- Database authorization through `dbauthz` package
## Frontend
For building Frontend refer to [this document](docs/contributing/frontend.md)
+2
View File
@@ -4,3 +4,5 @@ agent/proto/ @spikecurtis @johnstcn
tailnet/proto/ @spikecurtis @johnstcn
vpn/vpn.proto @spikecurtis @johnstcn
vpn/version.go @spikecurtis @johnstcn
provisionerd/proto/ @spikecurtis @johnstcn
provisionersdk/proto/ @spikecurtis @johnstcn
+130 -52
View File
@@ -54,6 +54,16 @@ FIND_EXCLUSIONS= \
-not \( \( -path '*/.git/*' -o -path './build/*' -o -path './vendor/*' -o -path './.coderv2/*' -o -path '*/node_modules/*' -o -path '*/out/*' -o -path './coderd/apidoc/*' -o -path '*/.next/*' -o -path '*/.terraform/*' \) -prune \)
# Source files used for make targets, evaluated on use.
GO_SRC_FILES := $(shell find . $(FIND_EXCLUSIONS) -type f -name '*.go' -not -name '*_test.go')
# Same as GO_SRC_FILES but excluding certain files that have problematic
# Makefile dependencies (e.g. pnpm).
MOST_GO_SRC_FILES := $(shell \
find . \
$(FIND_EXCLUSIONS) \
-type f \
-name '*.go' \
-not -name '*_test.go' \
-not -wholename './agent/agentcontainers/dcspec/dcspec_gen.go' \
)
# All the shell files in the repo, excluding ignored files.
SHELL_SRC_FILES := $(shell find . $(FIND_EXCLUSIONS) -type f -name '*.sh')
@@ -240,10 +250,14 @@ $(CODER_ALL_BINARIES): go.mod go.sum \
fi
cp "$@" "./site/out/bin/coder-$$os-$$arch$$dot_ext"
if [[ "$${CODER_SIGN_GPG:-0}" == "1" ]]; then
cp "$@.asc" "./site/out/bin/coder-$$os-$$arch$$dot_ext.asc"
fi
fi
# This task builds Coder Desktop dylibs
$(CODER_DYLIBS): go.mod go.sum $(GO_SRC_FILES)
$(CODER_DYLIBS): go.mod go.sum $(MOST_GO_SRC_FILES)
@if [ "$(shell uname)" = "Darwin" ]; then
$(get-mode-os-arch-ext)
./scripts/build_go.sh \
@@ -388,16 +402,21 @@ $(foreach chart,$(charts),build/$(chart)_helm_$(VERSION).tgz): build/%_helm_$(VE
--chart $* \
--output "$@"
node_modules/.installed: package.json
node_modules/.installed: package.json pnpm-lock.yaml
./scripts/pnpm_install.sh
touch "$@"
offlinedocs/node_modules/.installed: offlinedocs/package.json
cd offlinedocs/
../scripts/pnpm_install.sh
offlinedocs/node_modules/.installed: offlinedocs/package.json offlinedocs/pnpm-lock.yaml
(cd offlinedocs/ && ../scripts/pnpm_install.sh)
touch "$@"
site/node_modules/.installed: site/package.json
cd site/
../scripts/pnpm_install.sh
site/node_modules/.installed: site/package.json site/pnpm-lock.yaml
(cd site/ && ../scripts/pnpm_install.sh)
touch "$@"
scripts/apidocgen/node_modules/.installed: scripts/apidocgen/package.json scripts/apidocgen/pnpm-lock.yaml
(cd scripts/apidocgen && ../../scripts/pnpm_install.sh)
touch "$@"
SITE_GEN_FILES := \
site/src/api/typesGenerated.ts \
@@ -505,7 +524,7 @@ lint/ts: site/node_modules/.installed
lint/go:
./scripts/check_enterprise_imports.sh
./scripts/check_codersdk_imports.sh
linter_ver=$(shell egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/contents/Dockerfile | cut -d '=' -f 2)
linter_ver=$(shell egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/coder/Dockerfile | cut -d '=' -f 2)
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v$$linter_ver run
.PHONY: lint/go
@@ -559,21 +578,35 @@ GEN_FILES := \
docs/reference/cli/index.md \
docs/admin/security/audit-logs.md \
coderd/apidoc/swagger.json \
docs/manifest.json \
provisioner/terraform/testdata/version \
site/e2e/provisionerGenerated.ts \
examples/examples.gen.json \
$(TAILNETTEST_MOCKS) \
coderd/database/pubsub/psmock/psmock.go \
agent/agentcontainers/acmock/acmock.go
agent/agentcontainers/acmock/acmock.go \
agent/agentcontainers/dcspec/dcspec_gen.go \
coderd/httpmw/loggermw/loggermock/loggermock.go
# all gen targets should be added here and to gen/mark-fresh
gen: gen/db $(GEN_FILES)
gen: gen/db gen/golden-files $(GEN_FILES)
.PHONY: gen
gen/db: $(DB_GEN_FILES)
.PHONY: gen/db
gen/golden-files: \
cli/testdata/.gen-golden \
coderd/.gen-golden \
coderd/notifications/.gen-golden \
enterprise/cli/testdata/.gen-golden \
enterprise/tailnet/testdata/.gen-golden \
helm/coder/tests/testdata/.gen-golden \
helm/provisioner/tests/testdata/.gen-golden \
provisioner/terraform/testdata/.gen-golden \
tailnet/testdata/.gen-golden
.PHONY: gen/golden-files
# Mark all generated files as fresh so make thinks they're up-to-date. This is
# used during releases so we don't run generation scripts.
gen/mark-fresh:
@@ -594,12 +627,15 @@ gen/mark-fresh:
docs/reference/cli/index.md \
docs/admin/security/audit-logs.md \
coderd/apidoc/swagger.json \
docs/manifest.json \
site/e2e/provisionerGenerated.ts \
site/src/theme/icons.json \
examples/examples.gen.json \
$(TAILNETTEST_MOCKS) \
coderd/database/pubsub/psmock/psmock.go \
agent/agentcontainers/acmock/acmock.go \
agent/agentcontainers/dcspec/dcspec_gen.go \
coderd/httpmw/loggermw/loggermock/loggermock.go \
"
for file in $$files; do
@@ -618,24 +654,42 @@ gen/mark-fresh:
# applied.
coderd/database/dump.sql: coderd/database/gen/dump/main.go $(wildcard coderd/database/migrations/*.sql)
go run ./coderd/database/gen/dump/main.go
touch "$@"
# Generates Go code for querying the database.
# coderd/database/queries.sql.go
# coderd/database/models.go
coderd/database/querier.go: coderd/database/sqlc.yaml coderd/database/dump.sql $(wildcard coderd/database/queries/*.sql)
./coderd/database/generate.sh
touch "$@"
coderd/database/dbmock/dbmock.go: coderd/database/db.go coderd/database/querier.go
go generate ./coderd/database/dbmock/
touch "$@"
coderd/database/pubsub/psmock/psmock.go: coderd/database/pubsub/pubsub.go
go generate ./coderd/database/pubsub/psmock
touch "$@"
agent/agentcontainers/acmock/acmock.go: agent/agentcontainers/containers.go
go generate ./agent/agentcontainers/acmock/
touch "$@"
coderd/httpmw/loggermw/loggermock/loggermock.go: coderd/httpmw/loggermw/logger.go
go generate ./coderd/httpmw/loggermw/loggermock/
touch "$@"
agent/agentcontainers/dcspec/dcspec_gen.go: \
node_modules/.installed \
agent/agentcontainers/dcspec/devContainer.base.schema.json \
agent/agentcontainers/dcspec/gen.sh \
agent/agentcontainers/dcspec/doc.go
DCSPEC_QUIET=true go generate ./agent/agentcontainers/dcspec/
touch "$@"
$(TAILNETTEST_MOCKS): tailnet/coordinator.go tailnet/service.go
go generate ./tailnet/tailnettest/
touch "$@"
tailnet/proto/tailnet.pb.go: tailnet/proto/tailnet.proto
protoc \
@@ -678,77 +732,94 @@ vpn/vpn.pb.go: vpn/vpn.proto
site/src/api/typesGenerated.ts: site/node_modules/.installed $(wildcard scripts/apitypings/*) $(shell find ./codersdk $(FIND_EXCLUSIONS) -type f -name '*.go')
# -C sets the directory for the go run command
go run -C ./scripts/apitypings main.go > $@
cd site/
pnpm exec biome format --write src/api/typesGenerated.ts
(cd site/ && pnpm exec biome format --write src/api/typesGenerated.ts)
touch "$@"
site/e2e/provisionerGenerated.ts: site/node_modules/.installed provisionerd/proto/provisionerd.pb.go provisionersdk/proto/provisioner.pb.go
cd site/
pnpm run gen:provisioner
(cd site/ && pnpm run gen:provisioner)
touch "$@"
site/src/theme/icons.json: site/node_modules/.installed $(wildcard scripts/gensite/*) $(wildcard site/static/icon/*)
go run ./scripts/gensite/ -icons "$@"
cd site/
pnpm exec biome format --write src/theme/icons.json
(cd site/ && pnpm exec biome format --write src/theme/icons.json)
touch "$@"
examples/examples.gen.json: scripts/examplegen/main.go examples/examples.go $(shell find ./examples/templates)
go run ./scripts/examplegen/main.go > examples/examples.gen.json
touch "$@"
coderd/rbac/object_gen.go: scripts/typegen/rbacobject.gotmpl scripts/typegen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go
tempdir=$(shell mktemp -d /tmp/typegen_rbac_object.XXXXXX)
go run ./scripts/typegen/main.go rbac object > "$$tempdir/object_gen.go"
mv -v "$$tempdir/object_gen.go" coderd/rbac/object_gen.go
rmdir -v "$$tempdir"
touch "$@"
codersdk/rbacresources_gen.go: scripts/typegen/codersdk.gotmpl scripts/typegen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go
# Do no overwrite codersdk/rbacresources_gen.go directly, as it would make the file empty, breaking
# the `codersdk` package and any parallel build targets.
go run scripts/typegen/main.go rbac codersdk > /tmp/rbacresources_gen.go
mv /tmp/rbacresources_gen.go codersdk/rbacresources_gen.go
touch "$@"
site/src/api/rbacresourcesGenerated.ts: site/node_modules/.installed scripts/typegen/codersdk.gotmpl scripts/typegen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go
go run scripts/typegen/main.go rbac typescript > "$@"
cd site/
pnpm exec biome format --write src/api/rbacresourcesGenerated.ts
(cd site/ && pnpm exec biome format --write src/api/rbacresourcesGenerated.ts)
touch "$@"
site/src/api/countriesGenerated.ts: site/node_modules/.installed scripts/typegen/countries.tstmpl scripts/typegen/main.go codersdk/countries.go
go run scripts/typegen/main.go countries > "$@"
cd site/
pnpm exec biome format --write src/api/countriesGenerated.ts
(cd site/ && pnpm exec biome format --write src/api/countriesGenerated.ts)
touch "$@"
docs/admin/integrations/prometheus.md: node_modules/.installed scripts/metricsdocgen/main.go scripts/metricsdocgen/metrics
go run scripts/metricsdocgen/main.go
pnpm exec markdownlint-cli2 --fix ./docs/admin/integrations/prometheus.md
pnpm exec markdown-table-formatter ./docs/admin/integrations/prometheus.md
touch "$@"
docs/reference/cli/index.md: node_modules/.installed site/node_modules/.installed scripts/clidocgen/main.go examples/examples.gen.json $(GO_SRC_FILES)
docs/reference/cli/index.md: node_modules/.installed scripts/clidocgen/main.go examples/examples.gen.json $(GO_SRC_FILES)
CI=true BASE_PATH="." go run ./scripts/clidocgen
pnpm exec markdownlint-cli2 --fix ./docs/reference/cli/*.md
pnpm exec markdown-table-formatter ./docs/reference/cli/*.md
cd site/
pnpm exec biome format --write ../docs/manifest.json
touch "$@"
docs/admin/security/audit-logs.md: node_modules/.installed coderd/database/querier.go scripts/auditdocgen/main.go enterprise/audit/table.go coderd/rbac/object_gen.go
go run scripts/auditdocgen/main.go
pnpm exec markdownlint-cli2 --fix ./docs/admin/security/audit-logs.md
pnpm exec markdown-table-formatter ./docs/admin/security/audit-logs.md
touch "$@"
coderd/apidoc/swagger.json: node_modules/.installed site/node_modules/.installed $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS) -type f) $(wildcard coderd/*.go) $(wildcard enterprise/coderd/*.go) $(wildcard codersdk/*.go) $(wildcard enterprise/wsproxy/wsproxysdk/*.go) $(DB_GEN_FILES) .swaggo docs/manifest.json coderd/rbac/object_gen.go
coderd/apidoc/.gen: \
node_modules/.installed \
scripts/apidocgen/node_modules/.installed \
$(wildcard coderd/*.go) \
$(wildcard enterprise/coderd/*.go) \
$(wildcard codersdk/*.go) \
$(wildcard enterprise/wsproxy/wsproxysdk/*.go) \
$(DB_GEN_FILES) \
coderd/rbac/object_gen.go \
.swaggo \
scripts/apidocgen/generate.sh \
$(wildcard scripts/apidocgen/postprocess/*) \
$(wildcard scripts/apidocgen/markdown-template/*)
./scripts/apidocgen/generate.sh
pnpm exec markdownlint-cli2 --fix ./docs/reference/api/*.md
pnpm exec markdown-table-formatter ./docs/reference/api/*.md
cd site/
pnpm exec biome format --write ../docs/manifest.json ../coderd/apidoc/swagger.json
touch "$@"
update-golden-files: \
cli/testdata/.gen-golden \
coderd/.gen-golden \
coderd/notifications/.gen-golden \
enterprise/cli/testdata/.gen-golden \
enterprise/tailnet/testdata/.gen-golden \
helm/coder/tests/testdata/.gen-golden \
helm/provisioner/tests/testdata/.gen-golden \
provisioner/terraform/testdata/.gen-golden \
tailnet/testdata/.gen-golden
docs/manifest.json: site/node_modules/.installed coderd/apidoc/.gen docs/reference/cli/index.md
(cd site/ && pnpm exec biome format --write ../docs/manifest.json)
touch "$@"
coderd/apidoc/swagger.json: site/node_modules/.installed coderd/apidoc/.gen
(cd site/ && pnpm exec biome format --write ../coderd/apidoc/swagger.json)
touch "$@"
update-golden-files:
echo 'WARNING: This target is deprecated. Use "make gen/golden-files" instead.' >&2
echo 'Running "make gen/golden-files"' >&2
make gen/golden-files
.PHONY: update-golden-files
clean/golden-files:
@@ -767,39 +838,39 @@ clean/golden-files:
.PHONY: clean/golden-files
cli/testdata/.gen-golden: $(wildcard cli/testdata/*.golden) $(wildcard cli/*.tpl) $(GO_SRC_FILES) $(wildcard cli/*_test.go)
go test ./cli -run="Test(CommandHelp|ServerYAML|ErrorExamples|.*Golden)" -update
TZ=UTC go test ./cli -run="Test(CommandHelp|ServerYAML|ErrorExamples|.*Golden)" -update
touch "$@"
enterprise/cli/testdata/.gen-golden: $(wildcard enterprise/cli/testdata/*.golden) $(wildcard cli/*.tpl) $(GO_SRC_FILES) $(wildcard enterprise/cli/*_test.go)
go test ./enterprise/cli -run="TestEnterpriseCommandHelp" -update
TZ=UTC go test ./enterprise/cli -run="TestEnterpriseCommandHelp" -update
touch "$@"
tailnet/testdata/.gen-golden: $(wildcard tailnet/testdata/*.golden.html) $(GO_SRC_FILES) $(wildcard tailnet/*_test.go)
go test ./tailnet -run="TestDebugTemplate" -update
TZ=UTC go test ./tailnet -run="TestDebugTemplate" -update
touch "$@"
enterprise/tailnet/testdata/.gen-golden: $(wildcard enterprise/tailnet/testdata/*.golden.html) $(GO_SRC_FILES) $(wildcard enterprise/tailnet/*_test.go)
go test ./enterprise/tailnet -run="TestDebugTemplate" -update
TZ=UTC go test ./enterprise/tailnet -run="TestDebugTemplate" -update
touch "$@"
helm/coder/tests/testdata/.gen-golden: $(wildcard helm/coder/tests/testdata/*.yaml) $(wildcard helm/coder/tests/testdata/*.golden) $(GO_SRC_FILES) $(wildcard helm/coder/tests/*_test.go)
go test ./helm/coder/tests -run=TestUpdateGoldenFiles -update
TZ=UTC go test ./helm/coder/tests -run=TestUpdateGoldenFiles -update
touch "$@"
helm/provisioner/tests/testdata/.gen-golden: $(wildcard helm/provisioner/tests/testdata/*.yaml) $(wildcard helm/provisioner/tests/testdata/*.golden) $(GO_SRC_FILES) $(wildcard helm/provisioner/tests/*_test.go)
go test ./helm/provisioner/tests -run=TestUpdateGoldenFiles -update
TZ=UTC go test ./helm/provisioner/tests -run=TestUpdateGoldenFiles -update
touch "$@"
coderd/.gen-golden: $(wildcard coderd/testdata/*/*.golden) $(GO_SRC_FILES) $(wildcard coderd/*_test.go)
go test ./coderd -run="Test.*Golden$$" -update
TZ=UTC go test ./coderd -run="Test.*Golden$$" -update
touch "$@"
coderd/notifications/.gen-golden: $(wildcard coderd/notifications/testdata/*/*.golden) $(GO_SRC_FILES) $(wildcard coderd/notifications/*_test.go)
go test ./coderd/notifications -run="Test.*Golden$$" -update
TZ=UTC go test ./coderd/notifications -run="Test.*Golden$$" -update
touch "$@"
provisioner/terraform/testdata/.gen-golden: $(wildcard provisioner/terraform/testdata/*/*.golden) $(GO_SRC_FILES) $(wildcard provisioner/terraform/*_test.go)
go test ./provisioner/terraform -run="Test.*Golden$$" -update
TZ=UTC go test ./provisioner/terraform -run="Test.*Golden$$" -update
touch "$@"
provisioner/terraform/testdata/version:
@@ -808,12 +879,19 @@ provisioner/terraform/testdata/version:
fi
.PHONY: provisioner/terraform/testdata/version
# Set the retry flags if TEST_RETRIES is set
ifdef TEST_RETRIES
GOTESTSUM_RETRY_FLAGS := --rerun-fails=$(TEST_RETRIES)
else
GOTESTSUM_RETRY_FLAGS :=
endif
test:
$(GIT_FLAGS) gotestsum --format standard-quiet -- -v -short -count=1 ./... $(if $(RUN),-run $(RUN))
$(GIT_FLAGS) gotestsum --format standard-quiet $(GOTESTSUM_RETRY_FLAGS) --packages="./..." -- -v -short -count=1 $(if $(RUN),-run $(RUN))
.PHONY: test
test-cli:
$(GIT_FLAGS) gotestsum --format standard-quiet -- -v -short -count=1 ./cli/...
$(GIT_FLAGS) gotestsum --format standard-quiet $(GOTESTSUM_RETRY_FLAGS) --packages="./cli/..." -- -v -short -count=1
.PHONY: test-cli
# sqlc-cloud-is-setup will fail if no SQLc auth token is set. Use this as a
@@ -852,9 +930,9 @@ test-postgres: test-postgres-docker
$(GIT_FLAGS) DB=ci gotestsum \
--junitfile="gotests.xml" \
--jsonfile="gotests.json" \
$(GOTESTSUM_RETRY_FLAGS) \
--packages="./..." -- \
-timeout=20m \
-failfast \
-count=1
.PHONY: test-postgres
@@ -963,5 +1041,5 @@ else
endif
.PHONY: test-e2e
dogfood/contents/nix.hash: flake.nix flake.lock
sha256sum flake.nix flake.lock >./dogfood/contents/nix.hash
dogfood/coder/nix.hash: flake.nix flake.lock
sha256sum flake.nix flake.lock >./dogfood/coder/nix.hash
+319 -74
View File
@@ -8,11 +8,13 @@ import (
"fmt"
"hash/fnv"
"io"
"net"
"net/http"
"net/netip"
"os"
"os/user"
"path/filepath"
"slices"
"sort"
"strconv"
"strings"
@@ -25,15 +27,16 @@ import (
"github.com/prometheus/common/expfmt"
"github.com/spf13/afero"
"go.uber.org/atomic"
"golang.org/x/exp/slices"
"golang.org/x/sync/errgroup"
"golang.org/x/xerrors"
"google.golang.org/protobuf/types/known/timestamppb"
"tailscale.com/net/speedtest"
"tailscale.com/tailcfg"
"tailscale.com/types/netlogtype"
"tailscale.com/util/clientmetric"
"cdr.dev/slog"
"github.com/coder/clistat"
"github.com/coder/coder/v2/agent/agentcontainers"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/agent/agentscripts"
@@ -42,7 +45,6 @@ import (
"github.com/coder/coder/v2/agent/proto/resourcesmonitor"
"github.com/coder/coder/v2/agent/reconnectingpty"
"github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/cli/clistat"
"github.com/coder/coder/v2/cli/gitauth"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk"
@@ -87,12 +89,14 @@ type Options struct {
ServiceBannerRefreshInterval time.Duration
BlockFileTransfer bool
Execer agentexec.Execer
ContainerLister agentcontainers.Lister
ExperimentalDevcontainersEnabled bool
ContainerAPIOptions []agentcontainers.Option // Enable ExperimentalDevcontainersEnabled for these to be effective.
}
type Client interface {
ConnectRPC24(ctx context.Context) (
proto.DRPCAgentClient24, tailnetproto.DRPCTailnetClient24, error,
ConnectRPC25(ctx context.Context) (
proto.DRPCAgentClient25, tailnetproto.DRPCTailnetClient25, error,
)
RewriteDERPMap(derpMap *tailcfg.DERPMap)
}
@@ -150,9 +154,6 @@ func New(options Options) Agent {
if options.Execer == nil {
options.Execer = agentexec.DefaultExecer
}
if options.ContainerLister == nil {
options.ContainerLister = agentcontainers.NewDocker(options.Execer)
}
hardCtx, hardCancel := context.WithCancel(context.Background())
gracefulCtx, gracefulCancel := context.WithCancel(hardCtx)
@@ -175,6 +176,7 @@ func New(options Options) Agent {
lifecycleUpdate: make(chan struct{}, 1),
lifecycleReported: make(chan codersdk.WorkspaceAgentLifecycle, 1),
lifecycleStates: []agentsdk.PostLifecycleRequest{{State: codersdk.WorkspaceAgentLifecycleCreated}},
reportConnectionsUpdate: make(chan struct{}, 1),
ignorePorts: options.IgnorePorts,
portCacheDuration: options.PortCacheDuration,
reportMetadataInterval: options.ReportMetadataInterval,
@@ -187,7 +189,9 @@ func New(options Options) Agent {
prometheusRegistry: prometheusRegistry,
metrics: newAgentMetrics(prometheusRegistry),
execer: options.Execer,
lister: options.ContainerLister,
experimentalDevcontainersEnabled: options.ExperimentalDevcontainersEnabled,
containerAPIOptions: options.ContainerAPIOptions,
}
// Initially, we have a closed channel, reflecting the fact that we are not initially connected.
// Each time we connect we replace the channel (while holding the closeMutex) with a new one
@@ -222,13 +226,21 @@ type agent struct {
// we track 2 contexts and associated cancel functions: "graceful" which is Done when it is time
// to start gracefully shutting down and "hard" which is Done when it is time to close
// everything down (regardless of whether graceful shutdown completed).
gracefulCtx context.Context
gracefulCancel context.CancelFunc
hardCtx context.Context
hardCancel context.CancelFunc
closeWaitGroup sync.WaitGroup
gracefulCtx context.Context
gracefulCancel context.CancelFunc
hardCtx context.Context
hardCancel context.CancelFunc
// closeMutex protects the following:
closeMutex sync.Mutex
closeWaitGroup sync.WaitGroup
coordDisconnected chan struct{}
closing bool
// note that once the network is set to non-nil, it is never modified, as with the statsReporter. So, routines
// that run after createOrUpdateNetwork and check the networkOK checkpoint do not need to hold the lock to use them.
network *tailnet.Conn
statsReporter *statsReporter
// end fields protected by closeMutex
environmentVariables map[string]string
@@ -248,19 +260,26 @@ type agent struct {
lifecycleStates []agentsdk.PostLifecycleRequest
lifecycleLastReportedIndex int // Keeps track of the last lifecycle state we successfully reported.
network *tailnet.Conn
statsReporter *statsReporter
logSender *agentsdk.LogSender
reportConnectionsUpdate chan struct{}
reportConnectionsMu sync.Mutex
reportConnections []*proto.ReportConnectionRequest
logSender *agentsdk.LogSender
prometheusRegistry *prometheus.Registry
// metrics are prometheus registered metrics that will be collected and
// labeled in Coder with the agent + workspace.
metrics *agentMetrics
execer agentexec.Execer
lister agentcontainers.Lister
experimentalDevcontainersEnabled bool
containerAPIOptions []agentcontainers.Option
containerAPI atomic.Pointer[agentcontainers.API] // Set by apiHandler.
}
func (a *agent) TailnetConn() *tailnet.Conn {
a.closeMutex.Lock()
defer a.closeMutex.Unlock()
return a.network
}
@@ -273,6 +292,26 @@ func (a *agent) init() {
UpdateEnv: a.updateCommandEnv,
WorkingDirectory: func() string { return a.manifest.Load().Directory },
BlockFileTransfer: a.blockFileTransfer,
ReportConnection: func(id uuid.UUID, magicType agentssh.MagicSessionType, ip string) func(code int, reason string) {
var connectionType proto.Connection_Type
switch magicType {
case agentssh.MagicSessionTypeSSH:
connectionType = proto.Connection_SSH
case agentssh.MagicSessionTypeVSCode:
connectionType = proto.Connection_VSCODE
case agentssh.MagicSessionTypeJetBrains:
connectionType = proto.Connection_JETBRAINS
case agentssh.MagicSessionTypeUnknown:
connectionType = proto.Connection_TYPE_UNSPECIFIED
default:
a.logger.Error(a.hardCtx, "unhandled magic session type when reporting connection", slog.F("magic_type", magicType))
connectionType = proto.Connection_TYPE_UNSPECIFIED
}
return a.reportConnection(id, connectionType, ip)
},
ExperimentalDevContainersEnabled: a.experimentalDevcontainersEnabled,
})
if err != nil {
panic(err)
@@ -295,8 +334,14 @@ func (a *agent) init() {
a.reconnectingPTYServer = reconnectingpty.NewServer(
a.logger.Named("reconnecting-pty"),
a.sshServer,
func(id uuid.UUID, ip string) func(code int, reason string) {
return a.reportConnection(id, proto.Connection_RECONNECTING_PTY, ip)
},
a.metrics.connectionsTotal, a.metrics.reconnectingPTYErrors,
a.reconnectingPTYTimeout,
func(s *reconnectingpty.Server) {
s.ExperimentalDevcontainersEnabled = a.experimentalDevcontainersEnabled
},
)
go a.runLoop()
}
@@ -318,9 +363,11 @@ func (a *agent) runLoop() {
if ctx.Err() != nil {
// Context canceled errors may come from websocket pings, so we
// don't want to use `errors.Is(err, context.Canceled)` here.
a.logger.Warn(ctx, "runLoop exited with error", slog.Error(ctx.Err()))
return
}
if a.isClosed() {
a.logger.Warn(ctx, "runLoop exited because agent is closed")
return
}
if errors.Is(err, io.EOF) {
@@ -704,6 +751,124 @@ func (a *agent) setLifecycle(state codersdk.WorkspaceAgentLifecycle) {
}
}
// reportConnectionsLoop reports connections to the agent for auditing.
func (a *agent) reportConnectionsLoop(ctx context.Context, aAPI proto.DRPCAgentClient24) error {
for {
select {
case <-a.reportConnectionsUpdate:
case <-ctx.Done():
return ctx.Err()
}
for {
a.reportConnectionsMu.Lock()
if len(a.reportConnections) == 0 {
a.reportConnectionsMu.Unlock()
break
}
payload := a.reportConnections[0]
// Release lock while we send the payload, this is safe
// since we only append to the slice.
a.reportConnectionsMu.Unlock()
logger := a.logger.With(slog.F("payload", payload))
logger.Debug(ctx, "reporting connection")
_, err := aAPI.ReportConnection(ctx, payload)
if err != nil {
return xerrors.Errorf("failed to report connection: %w", err)
}
logger.Debug(ctx, "successfully reported connection")
// Remove the payload we sent.
a.reportConnectionsMu.Lock()
a.reportConnections[0] = nil // Release the pointer from the underlying array.
a.reportConnections = a.reportConnections[1:]
a.reportConnectionsMu.Unlock()
}
}
}
const (
// reportConnectionBufferLimit limits the number of connection reports we
// buffer to avoid growing the buffer indefinitely. This should not happen
// unless the agent has lost connection to coderd for a long time or if
// the agent is being spammed with connections.
//
// If we assume ~150 byte per connection report, this would be around 300KB
// of memory which seems acceptable. We could reduce this if necessary by
// not using the proto struct directly.
reportConnectionBufferLimit = 2048
)
func (a *agent) reportConnection(id uuid.UUID, connectionType proto.Connection_Type, ip string) (disconnected func(code int, reason string)) {
// Remove the port from the IP because ports are not supported in coderd.
if host, _, err := net.SplitHostPort(ip); err != nil {
a.logger.Error(a.hardCtx, "split host and port for connection report failed", slog.F("ip", ip), slog.Error(err))
} else {
// Best effort.
ip = host
}
a.reportConnectionsMu.Lock()
defer a.reportConnectionsMu.Unlock()
if len(a.reportConnections) >= reportConnectionBufferLimit {
a.logger.Warn(a.hardCtx, "connection report buffer limit reached, dropping connect",
slog.F("limit", reportConnectionBufferLimit),
slog.F("connection_id", id),
slog.F("connection_type", connectionType),
slog.F("ip", ip),
)
} else {
a.reportConnections = append(a.reportConnections, &proto.ReportConnectionRequest{
Connection: &proto.Connection{
Id: id[:],
Action: proto.Connection_CONNECT,
Type: connectionType,
Timestamp: timestamppb.New(time.Now()),
Ip: ip,
StatusCode: 0,
Reason: nil,
},
})
select {
case a.reportConnectionsUpdate <- struct{}{}:
default:
}
}
return func(code int, reason string) {
a.reportConnectionsMu.Lock()
defer a.reportConnectionsMu.Unlock()
if len(a.reportConnections) >= reportConnectionBufferLimit {
a.logger.Warn(a.hardCtx, "connection report buffer limit reached, dropping disconnect",
slog.F("limit", reportConnectionBufferLimit),
slog.F("connection_id", id),
slog.F("connection_type", connectionType),
slog.F("ip", ip),
)
return
}
a.reportConnections = append(a.reportConnections, &proto.ReportConnectionRequest{
Connection: &proto.Connection{
Id: id[:],
Action: proto.Connection_DISCONNECT,
Type: connectionType,
Timestamp: timestamppb.New(time.Now()),
Ip: ip,
StatusCode: int32(code), //nolint:gosec
Reason: &reason,
},
})
select {
case a.reportConnectionsUpdate <- struct{}{}:
default:
}
}
}
// fetchServiceBannerLoop fetches the service banner on an interval. It will
// not be fetched immediately; the expectation is that it is primed elsewhere
// (and must be done before the session actually starts).
@@ -743,14 +908,14 @@ func (a *agent) run() (retErr error) {
a.sessionToken.Store(&sessionToken)
// ConnectRPC returns the dRPC connection we use for the Agent and Tailnet v2+ APIs
aAPI, tAPI, err := a.client.ConnectRPC24(a.hardCtx)
aAPI, tAPI, err := a.client.ConnectRPC25(a.hardCtx)
if err != nil {
return err
}
defer func() {
cErr := aAPI.DRPCConn().Close()
if cErr != nil {
a.logger.Debug(a.hardCtx, "error closing drpc connection", slog.Error(err))
a.logger.Debug(a.hardCtx, "error closing drpc connection", slog.Error(cErr))
}
}()
@@ -779,7 +944,7 @@ func (a *agent) run() (retErr error) {
connMan.startAgentAPI("send logs", gracefulShutdownBehaviorRemain,
func(ctx context.Context, aAPI proto.DRPCAgentClient24) error {
err := a.logSender.SendLoop(ctx, aAPI)
if xerrors.Is(err, agentsdk.LogLimitExceededError) {
if xerrors.Is(err, agentsdk.ErrLogLimitExceeded) {
// we don't want this error to tear down the API connection and propagate to the
// other routines that use the API. The LogSender has already dropped a warning
// log, so just return nil here.
@@ -808,12 +973,19 @@ func (a *agent) run() (retErr error) {
if err != nil {
return xerrors.Errorf("failed to create resources fetcher: %w", err)
}
resourcesFetcher := resourcesmonitor.NewFetcher(statfetcher)
resourcesFetcher, err := resourcesmonitor.NewFetcher(statfetcher)
if err != nil {
return xerrors.Errorf("new resource fetcher: %w", err)
}
resourcesmonitor := resourcesmonitor.NewResourcesMonitor(logger, clk, config, resourcesFetcher, aAPI)
return resourcesmonitor.Start(ctx)
})
// Connection reports are part of auditing, we should keep sending them via
// gracefulShutdownBehaviorRemain.
connMan.startAgentAPI("report connections", gracefulShutdownBehaviorRemain, a.reportConnectionsLoop)
// channels to sync goroutines below
// handle manifest
// |
@@ -876,7 +1048,11 @@ func (a *agent) run() (retErr error) {
return a.statsReporter.reportLoop(ctx, aAPI)
})
return connMan.wait()
err = connMan.wait()
if err != nil {
a.logger.Info(context.Background(), "connection manager errored", slog.Error(err))
}
return err
}
// handleManifest returns a function that fetches and processes the manifest
@@ -911,10 +1087,12 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
//
// An example is VS Code Remote, which must know the directory
// before initializing a connection.
manifest.Directory, err = expandDirectory(manifest.Directory)
manifest.Directory, err = expandPathToAbs(manifest.Directory)
if err != nil {
return xerrors.Errorf("expand directory: %w", err)
}
// Normalize all devcontainer paths by making them absolute.
manifest.Devcontainers = agentcontainers.ExpandAllDevcontainerPaths(a.logger, expandPathToAbs, manifest.Devcontainers)
subsys, err := agentsdk.ProtoFromSubsystems(a.subsystems)
if err != nil {
a.logger.Critical(ctx, "failed to convert subsystems", slog.Error(err))
@@ -951,16 +1129,35 @@ func (a *agent) handleManifest(manifestOK *checkpoint) func(ctx context.Context,
}
}
err = a.scriptRunner.Init(manifest.Scripts, aAPI.ScriptCompleted)
var (
scripts = manifest.Scripts
scriptRunnerOpts []agentscripts.InitOption
)
if a.experimentalDevcontainersEnabled {
var dcScripts []codersdk.WorkspaceAgentScript
scripts, dcScripts = agentcontainers.ExtractAndInitializeDevcontainerScripts(manifest.Devcontainers, scripts)
// See ExtractAndInitializeDevcontainerScripts for motivation
// behind running dcScripts as post start scripts.
scriptRunnerOpts = append(scriptRunnerOpts, agentscripts.WithPostStartScripts(dcScripts...))
}
err = a.scriptRunner.Init(scripts, aAPI.ScriptCompleted, scriptRunnerOpts...)
if err != nil {
return xerrors.Errorf("init script runner: %w", err)
}
err = a.trackGoroutine(func() {
start := time.Now()
// here we use the graceful context because the script runner is not directly tied
// to the agent API.
// Here we use the graceful context because the script runner is
// not directly tied to the agent API.
//
// First we run the start scripts to ensure the workspace has
// been initialized and then the post start scripts which may
// depend on the workspace start scripts.
//
// Measure the time immediately after the start scripts have
// finished (both start and post start). For instance, an
// autostarted devcontainer will be included in this time.
err := a.scriptRunner.Execute(a.gracefulCtx, agentscripts.ExecuteStartScripts)
// Measure the time immediately after the script has finished
err = errors.Join(err, a.scriptRunner.Execute(a.gracefulCtx, agentscripts.ExecutePostStartScripts))
dur := time.Since(start).Seconds()
if err != nil {
a.logger.Warn(ctx, "startup script(s) failed", slog.Error(err))
@@ -1003,9 +1200,9 @@ func (a *agent) createOrUpdateNetwork(manifestOK, networkOK *checkpoint) func(co
network := a.network
a.closeMutex.Unlock()
if network == nil {
keySeed, err := WorkspaceKeySeed(manifest.WorkspaceID, manifest.AgentName)
keySeed, err := SSHKeySeed(manifest.OwnerName, manifest.WorkspaceName, manifest.AgentName)
if err != nil {
return xerrors.Errorf("generate seed from workspace id: %w", err)
return xerrors.Errorf("generate SSH key seed: %w", err)
}
// use the graceful context here, because creating the tailnet is not itself tied to the
// agent API.
@@ -1022,15 +1219,15 @@ func (a *agent) createOrUpdateNetwork(manifestOK, networkOK *checkpoint) func(co
}
a.closeMutex.Lock()
// Re-check if agent was closed while initializing the network.
closed := a.isClosed()
if !closed {
closing := a.closing
if !closing {
a.network = network
a.statsReporter = newStatsReporter(a.logger, network, a)
}
a.closeMutex.Unlock()
if closed {
if closing {
_ = network.Close()
return xerrors.New("agent is closed")
return xerrors.New("agent is closing")
}
} else {
// Update the wireguard IPs if the agent ID changed.
@@ -1145,8 +1342,8 @@ func (*agent) wireguardAddresses(agentID uuid.UUID) []netip.Prefix {
func (a *agent) trackGoroutine(fn func()) error {
a.closeMutex.Lock()
defer a.closeMutex.Unlock()
if a.isClosed() {
return xerrors.New("track conn goroutine: agent is closed")
if a.closing {
return xerrors.New("track conn goroutine: agent is closing")
}
a.closeWaitGroup.Add(1)
go func() {
@@ -1225,7 +1422,7 @@ func (a *agent) createTailnet(
if rPTYServeErr != nil &&
a.gracefulCtx.Err() == nil &&
!strings.Contains(rPTYServeErr.Error(), "use of closed network connection") {
a.logger.Error(ctx, "error serving reconnecting PTY", slog.Error(err))
a.logger.Error(ctx, "error serving reconnecting PTY", slog.Error(rPTYServeErr))
}
}); err != nil {
return nil, err
@@ -1290,8 +1487,13 @@ func (a *agent) createTailnet(
}()
if err = a.trackGoroutine(func() {
defer apiListener.Close()
apiHandler, closeAPIHAndler := a.apiHandler()
defer func() {
_ = closeAPIHAndler()
}()
server := &http.Server{
Handler: a.apiHandler(),
BaseContext: func(net.Listener) context.Context { return ctx },
Handler: apiHandler,
ReadTimeout: 20 * time.Second,
ReadHeaderTimeout: 20 * time.Second,
WriteTimeout: 20 * time.Second,
@@ -1302,6 +1504,7 @@ func (a *agent) createTailnet(
case <-ctx.Done():
case <-a.hardCtx.Done():
}
_ = closeAPIHAndler()
_ = server.Close()
}()
@@ -1335,14 +1538,11 @@ func (a *agent) runCoordinator(ctx context.Context, tClient tailnetproto.DRPCTai
a.logger.Info(ctx, "connected to coordination RPC")
// This allows the Close() routine to wait for the coordinator to gracefully disconnect.
a.closeMutex.Lock()
if a.isClosed() {
return nil
disconnected := a.setCoordDisconnected()
if disconnected == nil {
return nil // already closed by something else
}
disconnected := make(chan struct{})
a.coordDisconnected = disconnected
defer close(disconnected)
a.closeMutex.Unlock()
ctrl := tailnet.NewAgentCoordinationController(a.logger, network)
coordination := ctrl.New(coordinate)
@@ -1364,6 +1564,17 @@ func (a *agent) runCoordinator(ctx context.Context, tClient tailnetproto.DRPCTai
return <-errCh
}
func (a *agent) setCoordDisconnected() chan struct{} {
a.closeMutex.Lock()
defer a.closeMutex.Unlock()
if a.closing {
return nil
}
disconnected := make(chan struct{})
a.coordDisconnected = disconnected
return disconnected
}
// runDERPMapSubscriber runs a coordinator and returns if a reconnect should occur.
func (a *agent) runDERPMapSubscriber(ctx context.Context, tClient tailnetproto.DRPCTailnetClient24, network *tailnet.Conn) error {
defer a.logger.Debug(ctx, "disconnected from derp map RPC")
@@ -1400,9 +1611,13 @@ func (a *agent) Collect(ctx context.Context, networkStats map[netlogtype.Connect
}
for conn, counts := range networkStats {
stats.ConnectionsByProto[conn.Proto.String()]++
// #nosec G115 - Safe conversions for network statistics which we expect to be within int64 range
stats.RxBytes += int64(counts.RxBytes)
// #nosec G115 - Safe conversions for network statistics which we expect to be within int64 range
stats.RxPackets += int64(counts.RxPackets)
// #nosec G115 - Safe conversions for network statistics which we expect to be within int64 range
stats.TxBytes += int64(counts.TxBytes)
// #nosec G115 - Safe conversions for network statistics which we expect to be within int64 range
stats.TxPackets += int64(counts.TxPackets)
}
@@ -1455,11 +1670,12 @@ func (a *agent) Collect(ctx context.Context, networkStats map[netlogtype.Connect
wg.Wait()
sort.Float64s(durations)
durationsLength := len(durations)
if durationsLength == 0 {
switch {
case durationsLength == 0:
stats.ConnectionMedianLatencyMs = -1
} else if durationsLength%2 == 0 {
case durationsLength%2 == 0:
stats.ConnectionMedianLatencyMs = (durations[durationsLength/2-1] + durations[durationsLength/2]) / 2
} else {
default:
stats.ConnectionMedianLatencyMs = durations[durationsLength/2]
}
// Convert from microseconds to milliseconds.
@@ -1566,7 +1782,7 @@ func (a *agent) HTTPDebug() http.Handler {
r.Get("/debug/magicsock", a.HandleHTTPDebugMagicsock)
r.Get("/debug/magicsock/debug-logging/{state}", a.HandleHTTPMagicsockDebugLoggingState)
r.Get("/debug/manifest", a.HandleHTTPDebugManifest)
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
r.NotFound(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write([]byte("404 not found"))
})
@@ -1576,7 +1792,10 @@ func (a *agent) HTTPDebug() http.Handler {
func (a *agent) Close() error {
a.closeMutex.Lock()
defer a.closeMutex.Unlock()
network := a.network
coordDisconnected := a.coordDisconnected
a.closing = true
a.closeMutex.Unlock()
if a.isClosed() {
return nil
}
@@ -1585,15 +1804,22 @@ func (a *agent) Close() error {
a.setLifecycle(codersdk.WorkspaceAgentLifecycleShuttingDown)
// Attempt to gracefully shut down all active SSH connections and
// stop accepting new ones.
err := a.sshServer.Shutdown(a.hardCtx)
// stop accepting new ones. If all processes have not exited after 5
// seconds, we just log it and move on as it's more important to run
// the shutdown scripts. A typical shutdown time for containers is
// 10 seconds, so this still leaves a bit of time to run the
// shutdown scripts in the worst-case.
sshShutdownCtx, sshShutdownCancel := context.WithTimeout(a.hardCtx, 5*time.Second)
defer sshShutdownCancel()
err := a.sshServer.Shutdown(sshShutdownCtx)
if err != nil {
a.logger.Error(a.hardCtx, "ssh server shutdown", slog.Error(err))
}
err = a.sshServer.Close()
if err != nil {
a.logger.Error(a.hardCtx, "ssh server close", slog.Error(err))
if errors.Is(err, context.DeadlineExceeded) {
a.logger.Warn(sshShutdownCtx, "ssh server shutdown timeout", slog.Error(err))
} else {
a.logger.Error(sshShutdownCtx, "ssh server shutdown", slog.Error(err))
}
}
// wait for SSH to shut down before the general graceful cancel, because
// this triggers a disconnect in the tailnet layer, telling all clients to
// shut down their wireguard tunnels to us. If SSH sessions are still up,
@@ -1646,7 +1872,7 @@ lifecycleWaitLoop:
select {
case <-a.hardCtx.Done():
a.logger.Warn(context.Background(), "timed out waiting for Coordinator RPC disconnect")
case <-a.coordDisconnected:
case <-coordDisconnected:
a.logger.Debug(context.Background(), "coordinator RPC disconnected")
}
@@ -1657,8 +1883,8 @@ lifecycleWaitLoop:
}
a.hardCancel()
if a.network != nil {
_ = a.network.Close()
if network != nil {
_ = network.Close()
}
a.closeWaitGroup.Wait()
@@ -1682,30 +1908,29 @@ func userHomeDir() (string, error) {
return u.HomeDir, nil
}
// expandDirectory converts a directory path to an absolute path.
// It primarily resolves the home directory and any environment
// variables that may be set
func expandDirectory(dir string) (string, error) {
if dir == "" {
// expandPathToAbs converts a path to an absolute path. It primarily resolves
// the home directory and any environment variables that may be set.
func expandPathToAbs(path string) (string, error) {
if path == "" {
return "", nil
}
if dir[0] == '~' {
if path[0] == '~' {
home, err := userHomeDir()
if err != nil {
return "", err
}
dir = filepath.Join(home, dir[1:])
path = filepath.Join(home, path[1:])
}
dir = os.ExpandEnv(dir)
path = os.ExpandEnv(path)
if !filepath.IsAbs(dir) {
if !filepath.IsAbs(path) {
home, err := userHomeDir()
if err != nil {
return "", err
}
dir = filepath.Join(home, dir)
path = filepath.Join(home, path)
}
return dir, nil
return path, nil
}
// EnvAgentSubsystem is the environment variable used to denote the
@@ -1852,7 +2077,7 @@ func (a *apiConnRoutineManager) wait() error {
}
func PrometheusMetricsHandler(prometheusRegistry *prometheus.Registry, logger slog.Logger) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "text/plain")
// Based on: https://github.com/tailscale/tailscale/blob/280255acae604796a1113861f5a84e6fa2dc6121/ipn/localapi/localapi.go#L489
@@ -1874,12 +2099,31 @@ func PrometheusMetricsHandler(prometheusRegistry *prometheus.Registry, logger sl
})
}
// WorkspaceKeySeed converts a WorkspaceID UUID and agent name to an int64 hash.
// SSHKeySeed converts an owner userName, workspaceName and agentName to an int64 hash.
// This uses the FNV-1a hash algorithm which provides decent distribution and collision
// resistance for string inputs.
func WorkspaceKeySeed(workspaceID uuid.UUID, agentName string) (int64, error) {
//
// Why owner username, workspace name, and agent name? These are the components that are used in hostnames for the
// workspace over SSH, and so we want the workspace to have a stable key with respect to these. We don't use the
// respective UUIDs. The workspace UUID would be different if you delete and recreate a workspace with the same name.
// The agent UUID is regenerated on each build. Since Coder's Tailnet networking is handling the authentication, we
// should not be showing users warnings about host SSH keys.
func SSHKeySeed(userName, workspaceName, agentName string) (int64, error) {
h := fnv.New64a()
_, err := h.Write(workspaceID[:])
_, err := h.Write([]byte(userName))
if err != nil {
return 42, err
}
// null separators between strings so that (dog, foodstuff) is distinct from (dogfood, stuff)
_, err = h.Write([]byte{0})
if err != nil {
return 42, err
}
_, err = h.Write([]byte(workspaceName))
if err != nil {
return 42, err
}
_, err = h.Write([]byte{0})
if err != nil {
return 42, err
}
@@ -1888,5 +2132,6 @@ func WorkspaceKeySeed(workspaceID uuid.UUID, agentName string) (int64, error) {
return 42, err
}
// #nosec G115 - Safe conversion to generate int64 hash from Sum64, data loss acceptable
return int64(h.Sum64()), nil
}
+548 -23
View File
@@ -19,14 +19,21 @@ import (
"path/filepath"
"regexp"
"runtime"
"slices"
"strconv"
"strings"
"sync/atomic"
"testing"
"time"
"go.uber.org/goleak"
"tailscale.com/net/speedtest"
"tailscale.com/tailcfg"
"github.com/bramvdbogaerde/go-scp"
"github.com/google/uuid"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
"github.com/pion/udp"
"github.com/pkg/sftp"
"github.com/prometheus/client_golang/prometheus"
@@ -34,19 +41,17 @@ import (
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
"golang.org/x/crypto/ssh"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"tailscale.com/net/speedtest"
"tailscale.com/tailcfg"
"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/agent"
"github.com/coder/coder/v2/agent/agentssh"
"github.com/coder/coder/v2/agent/agenttest"
"github.com/coder/coder/v2/agent/proto"
"github.com/coder/coder/v2/agent/usershell"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/coder/v2/codersdk/workspacesdk"
@@ -63,6 +68,54 @@ func TestMain(m *testing.M) {
var sshPorts = []uint16{workspacesdk.AgentSSHPort, workspacesdk.AgentStandardSSHPort}
// TestAgent_CloseWhileStarting is a regression test for https://github.com/coder/coder/issues/17328
func TestAgent_ImmediateClose(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
logger := slogtest.Make(t, &slogtest.Options{
// Agent can drop errors when shutting down, and some, like the
// fasthttplistener connection closed error, are unexported.
IgnoreErrors: true,
}).Leveled(slog.LevelDebug)
manifest := agentsdk.Manifest{
AgentID: uuid.New(),
AgentName: "test-agent",
WorkspaceName: "test-workspace",
WorkspaceID: uuid.New(),
}
coordinator := tailnet.NewCoordinator(logger)
t.Cleanup(func() {
_ = coordinator.Close()
})
statsCh := make(chan *proto.Stats, 50)
fs := afero.NewMemMapFs()
client := agenttest.NewClient(t, logger.Named("agenttest"), manifest.AgentID, manifest, statsCh, coordinator)
t.Cleanup(client.Close)
options := agent.Options{
Client: client,
Filesystem: fs,
Logger: logger.Named("agent"),
ReconnectingPTYTimeout: 0,
EnvironmentVariables: map[string]string{},
}
agentUnderTest := agent.New(options)
t.Cleanup(func() {
_ = agentUnderTest.Close()
})
// wait until the agent has connected and is starting to find races in the startup code
_ = testutil.TryReceive(ctx, t, client.GetStartup())
t.Log("Closing Agent")
err := agentUnderTest.Close()
require.NoError(t, err)
}
// NOTE: These tests only work when your default shell is bash for some reason.
func TestAgent_Stats_SSH(t *testing.T) {
@@ -169,7 +222,7 @@ func TestAgent_Stats_Magic(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
//nolint:dogsled
conn, _, stats, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
conn, agentClient, stats, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
sshClient, err := conn.SSHClient(ctx)
require.NoError(t, err)
defer sshClient.Close()
@@ -185,7 +238,7 @@ func TestAgent_Stats_Magic(t *testing.T) {
s, ok := <-stats
t.Logf("got stats: ok=%t, ConnectionCount=%d, RxBytes=%d, TxBytes=%d, SessionCountVSCode=%d, ConnectionMedianLatencyMS=%f",
ok, s.ConnectionCount, s.RxBytes, s.TxBytes, s.SessionCountVscode, s.ConnectionMedianLatencyMs)
return ok && s.ConnectionCount > 0 && s.RxBytes > 0 && s.TxBytes > 0 &&
return ok &&
// Ensure that the connection didn't count as a "normal" SSH session.
// This was a special one, so it should be labeled specially in the stats!
s.SessionCountVscode == 1 &&
@@ -199,6 +252,8 @@ func TestAgent_Stats_Magic(t *testing.T) {
_ = stdin.Close()
err = session.Wait()
require.NoError(t, err)
assertConnectionReport(t, agentClient, proto.Connection_VSCODE, 0, "")
})
t.Run("TracksJetBrains", func(t *testing.T) {
@@ -235,7 +290,7 @@ func TestAgent_Stats_Magic(t *testing.T) {
remotePort := sc.Text()
//nolint:dogsled
conn, _, stats, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
conn, agentClient, stats, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
sshClient, err := conn.SSHClient(ctx)
require.NoError(t, err)
@@ -251,8 +306,7 @@ func TestAgent_Stats_Magic(t *testing.T) {
s, ok := <-stats
t.Logf("got stats with conn open: ok=%t, ConnectionCount=%d, SessionCountJetBrains=%d",
ok, s.ConnectionCount, s.SessionCountJetbrains)
return ok && s.ConnectionCount > 0 &&
s.SessionCountJetbrains == 1
return ok && s.SessionCountJetbrains == 1
}, testutil.WaitLong, testutil.IntervalFast,
"never saw stats with conn open",
)
@@ -271,6 +325,8 @@ func TestAgent_Stats_Magic(t *testing.T) {
}, testutil.WaitLong, testutil.IntervalFast,
"never saw stats after conn closes",
)
assertConnectionReport(t, agentClient, proto.Connection_JETBRAINS, 0, "")
})
}
@@ -948,7 +1004,7 @@ func TestAgent_SFTP(t *testing.T) {
home = "/" + strings.ReplaceAll(home, "\\", "/")
}
//nolint:dogsled
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
sshClient, err := conn.SSHClient(ctx)
require.NoError(t, err)
defer sshClient.Close()
@@ -971,6 +1027,10 @@ func TestAgent_SFTP(t *testing.T) {
require.NoError(t, err)
_, err = os.Stat(tempFile)
require.NoError(t, err)
// Close the client to trigger disconnect event.
_ = client.Close()
assertConnectionReport(t, agentClient, proto.Connection_SSH, 0, "")
}
func TestAgent_SCP(t *testing.T) {
@@ -980,7 +1040,7 @@ func TestAgent_SCP(t *testing.T) {
defer cancel()
//nolint:dogsled
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
sshClient, err := conn.SSHClient(ctx)
require.NoError(t, err)
defer sshClient.Close()
@@ -993,6 +1053,10 @@ func TestAgent_SCP(t *testing.T) {
require.NoError(t, err)
_, err = os.Stat(tempFile)
require.NoError(t, err)
// Close the client to trigger disconnect event.
scpClient.Close()
assertConnectionReport(t, agentClient, proto.Connection_SSH, 0, "")
}
func TestAgent_FileTransferBlocked(t *testing.T) {
@@ -1017,7 +1081,7 @@ func TestAgent_FileTransferBlocked(t *testing.T) {
defer cancel()
//nolint:dogsled
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, func(_ *agenttest.Client, o *agent.Options) {
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, func(_ *agenttest.Client, o *agent.Options) {
o.BlockFileTransfer = true
})
sshClient, err := conn.SSHClient(ctx)
@@ -1026,6 +1090,8 @@ func TestAgent_FileTransferBlocked(t *testing.T) {
_, err = sftp.NewClient(sshClient)
require.Error(t, err)
assertFileTransferBlocked(t, err.Error())
assertConnectionReport(t, agentClient, proto.Connection_SSH, agentssh.BlockedFileTransferErrorCode, "")
})
t.Run("SCP with go-scp package", func(t *testing.T) {
@@ -1035,7 +1101,7 @@ func TestAgent_FileTransferBlocked(t *testing.T) {
defer cancel()
//nolint:dogsled
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, func(_ *agenttest.Client, o *agent.Options) {
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, func(_ *agenttest.Client, o *agent.Options) {
o.BlockFileTransfer = true
})
sshClient, err := conn.SSHClient(ctx)
@@ -1048,6 +1114,8 @@ func TestAgent_FileTransferBlocked(t *testing.T) {
err = scpClient.CopyFile(context.Background(), strings.NewReader("hello world"), tempFile, "0755")
require.Error(t, err)
assertFileTransferBlocked(t, err.Error())
assertConnectionReport(t, agentClient, proto.Connection_SSH, agentssh.BlockedFileTransferErrorCode, "")
})
t.Run("Forbidden commands", func(t *testing.T) {
@@ -1061,7 +1129,7 @@ func TestAgent_FileTransferBlocked(t *testing.T) {
defer cancel()
//nolint:dogsled
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, func(_ *agenttest.Client, o *agent.Options) {
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, func(_ *agenttest.Client, o *agent.Options) {
o.BlockFileTransfer = true
})
sshClient, err := conn.SSHClient(ctx)
@@ -1083,6 +1151,8 @@ func TestAgent_FileTransferBlocked(t *testing.T) {
msg, err := io.ReadAll(stdout)
require.NoError(t, err)
assertFileTransferBlocked(t, string(msg))
assertConnectionReport(t, agentClient, proto.Connection_SSH, agentssh.BlockedFileTransferErrorCode, "")
})
}
})
@@ -1171,6 +1241,49 @@ func TestAgent_SSHConnectionEnvVars(t *testing.T) {
}
}
func TestAgent_SSHConnectionLoginVars(t *testing.T) {
t.Parallel()
envInfo := usershell.SystemEnvInfo{}
u, err := envInfo.User()
require.NoError(t, err, "get current user")
shell, err := envInfo.Shell(u.Username)
require.NoError(t, err, "get current shell")
tests := []struct {
key string
want string
}{
{
key: "USER",
want: u.Username,
},
{
key: "LOGNAME",
want: u.Username,
},
{
key: "SHELL",
want: shell,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.key, func(t *testing.T) {
t.Parallel()
session := setupSSHSession(t, agentsdk.Manifest{}, codersdk.ServiceBannerConfig{}, nil)
command := "sh -c 'echo $" + tt.key + "'"
if runtime.GOOS == "windows" {
command = "cmd.exe /c echo %" + tt.key + "%"
}
output, err := session.Output(command)
require.NoError(t, err)
require.Equal(t, tt.want, strings.TrimSpace(string(output)))
})
}
}
func TestAgent_Metadata(t *testing.T) {
t.Parallel()
@@ -1385,7 +1498,7 @@ func TestAgent_Lifecycle(t *testing.T) {
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
Scripts: []codersdk.WorkspaceAgentScript{{
Script: "true",
Script: "echo foo",
Timeout: 30 * time.Second,
RunOnStart: true,
}},
@@ -1533,8 +1646,10 @@ func TestAgent_Lifecycle(t *testing.T) {
t.Run("ShutdownScriptOnce", func(t *testing.T) {
t.Parallel()
logger := testutil.Logger(t)
ctx := testutil.Context(t, testutil.WaitMedium)
expected := "this-is-shutdown"
derpMap, _ := tailnettest.RunDERPAndSTUN(t)
statsCh := make(chan *proto.Stats, 50)
client := agenttest.NewClient(t,
logger,
@@ -1553,7 +1668,7 @@ func TestAgent_Lifecycle(t *testing.T) {
RunOnStop: true,
}},
},
make(chan *proto.Stats, 50),
statsCh,
tailnet.NewCoordinator(logger),
)
defer client.Close()
@@ -1578,6 +1693,11 @@ func TestAgent_Lifecycle(t *testing.T) {
return len(content) > 0 // something is in the startup log file
}, testutil.WaitShort, testutil.IntervalMedium)
// In order to avoid shutting down the agent before it is fully started and triggering
// errors, we'll wait until the agent is fully up. It's a bit hokey, but among the last things the agent starts
// is the stats reporting, so getting a stats report is a good indication the agent is fully up.
_ = testutil.TryReceive(ctx, t, statsCh)
err := agent.Close()
require.NoError(t, err, "agent should be closed successfully")
@@ -1606,7 +1726,7 @@ func TestAgent_Startup(t *testing.T) {
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
Directory: "",
}, 0)
startup := testutil.RequireRecvCtx(ctx, t, client.GetStartup())
startup := testutil.TryReceive(ctx, t, client.GetStartup())
require.Equal(t, "", startup.GetExpandedDirectory())
})
@@ -1617,7 +1737,7 @@ func TestAgent_Startup(t *testing.T) {
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
Directory: "~",
}, 0)
startup := testutil.RequireRecvCtx(ctx, t, client.GetStartup())
startup := testutil.TryReceive(ctx, t, client.GetStartup())
homeDir, err := os.UserHomeDir()
require.NoError(t, err)
require.Equal(t, homeDir, startup.GetExpandedDirectory())
@@ -1630,7 +1750,7 @@ func TestAgent_Startup(t *testing.T) {
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
Directory: "coder/coder",
}, 0)
startup := testutil.RequireRecvCtx(ctx, t, client.GetStartup())
startup := testutil.TryReceive(ctx, t, client.GetStartup())
homeDir, err := os.UserHomeDir()
require.NoError(t, err)
require.Equal(t, filepath.Join(homeDir, "coder/coder"), startup.GetExpandedDirectory())
@@ -1643,7 +1763,7 @@ func TestAgent_Startup(t *testing.T) {
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
Directory: "$HOME",
}, 0)
startup := testutil.RequireRecvCtx(ctx, t, client.GetStartup())
startup := testutil.TryReceive(ctx, t, client.GetStartup())
homeDir, err := os.UserHomeDir()
require.NoError(t, err)
require.Equal(t, homeDir, startup.GetExpandedDirectory())
@@ -1691,8 +1811,16 @@ func TestAgent_ReconnectingPTY(t *testing.T) {
defer cancel()
//nolint:dogsled
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
id := uuid.New()
// Test that the connection is reported. This must be tested in the
// first connection because we care about verifying all of these.
netConn0, err := conn.ReconnectingPTY(ctx, id, 80, 80, "bash --norc")
require.NoError(t, err)
_ = netConn0.Close()
assertConnectionReport(t, agentClient, proto.Connection_RECONNECTING_PTY, 0, "")
// --norc disables executing .bashrc, which is often used to customize the bash prompt
netConn1, err := conn.ReconnectingPTY(ctx, id, 80, 80, "bash --norc")
require.NoError(t, err)
@@ -1791,6 +1919,371 @@ func TestAgent_ReconnectingPTY(t *testing.T) {
}
}
// This tests end-to-end functionality of connecting to a running container
// and executing a command. It creates a real Docker container and runs a
// command. As such, it does not run by default in CI.
// You can run it manually as follows:
//
// CODER_TEST_USE_DOCKER=1 go test -count=1 ./agent -run TestAgent_ReconnectingPTYContainer
func TestAgent_ReconnectingPTYContainer(t *testing.T) {
t.Parallel()
if os.Getenv("CODER_TEST_USE_DOCKER") != "1" {
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
}
pool, err := dockertest.NewPool("")
require.NoError(t, err, "Could not connect to docker")
ct, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: "busybox",
Tag: "latest",
Cmd: []string{"sleep", "infnity"},
}, func(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
})
require.NoError(t, err, "Could not start container")
defer func() {
err := pool.Purge(ct)
require.NoError(t, err, "Could not stop container")
}()
// Wait for container to start
require.Eventually(t, func() bool {
ct, ok := pool.ContainerByName(ct.Container.Name)
return ok && ct.Container.State.Running
}, testutil.WaitShort, testutil.IntervalSlow, "Container did not start in time")
// nolint: dogsled
conn, _, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, func(_ *agenttest.Client, o *agent.Options) {
o.ExperimentalDevcontainersEnabled = true
})
ctx := testutil.Context(t, testutil.WaitLong)
ac, err := conn.ReconnectingPTY(ctx, uuid.New(), 80, 80, "/bin/sh", func(arp *workspacesdk.AgentReconnectingPTYInit) {
arp.Container = ct.Container.ID
})
require.NoError(t, err, "failed to create ReconnectingPTY")
defer ac.Close()
tr := testutil.NewTerminalReader(t, ac)
require.NoError(t, tr.ReadUntil(ctx, func(line string) bool {
return strings.Contains(line, "#") || strings.Contains(line, "$")
}), "find prompt")
require.NoError(t, json.NewEncoder(ac).Encode(workspacesdk.ReconnectingPTYRequest{
Data: "hostname\r",
}), "write hostname")
require.NoError(t, tr.ReadUntil(ctx, func(line string) bool {
return strings.Contains(line, "hostname")
}), "find hostname command")
require.NoError(t, tr.ReadUntil(ctx, func(line string) bool {
return strings.Contains(line, ct.Container.Config.Hostname)
}), "find hostname output")
require.NoError(t, json.NewEncoder(ac).Encode(workspacesdk.ReconnectingPTYRequest{
Data: "exit\r",
}), "write exit command")
// Wait for the connection to close.
require.ErrorIs(t, tr.ReadUntil(ctx, nil), io.EOF)
}
// This tests end-to-end functionality of auto-starting a devcontainer.
// It runs "devcontainer up" which creates a real Docker container. As
// such, it does not run by default in CI.
//
// You can run it manually as follows:
//
// CODER_TEST_USE_DOCKER=1 go test -count=1 ./agent -run TestAgent_DevcontainerAutostart
//
//nolint:paralleltest // This test sets an environment variable.
func TestAgent_DevcontainerAutostart(t *testing.T) {
if os.Getenv("CODER_TEST_USE_DOCKER") != "1" {
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
}
pool, err := dockertest.NewPool("")
require.NoError(t, err, "Could not connect to docker")
// Prepare temporary devcontainer for test (mywork).
devcontainerID := uuid.New()
tmpdir := t.TempDir()
t.Setenv("HOME", tmpdir)
tempWorkspaceFolder := filepath.Join(tmpdir, "mywork")
unexpandedWorkspaceFolder := filepath.Join("~", "mywork")
t.Logf("Workspace folder: %s", tempWorkspaceFolder)
t.Logf("Unexpanded workspace folder: %s", unexpandedWorkspaceFolder)
devcontainerPath := filepath.Join(tempWorkspaceFolder, ".devcontainer")
err = os.MkdirAll(devcontainerPath, 0o755)
require.NoError(t, err, "create devcontainer directory")
devcontainerFile := filepath.Join(devcontainerPath, "devcontainer.json")
err = os.WriteFile(devcontainerFile, []byte(`{
"name": "mywork",
"image": "busybox:latest",
"cmd": ["sleep", "infinity"]
}`), 0o600)
require.NoError(t, err, "write devcontainer.json")
manifest := agentsdk.Manifest{
// Set up pre-conditions for auto-starting a devcontainer, the script
// is expected to be prepared by the provisioner normally.
Devcontainers: []codersdk.WorkspaceAgentDevcontainer{
{
ID: devcontainerID,
Name: "test",
// Use an unexpanded path to test the expansion.
WorkspaceFolder: unexpandedWorkspaceFolder,
},
},
Scripts: []codersdk.WorkspaceAgentScript{
{
ID: devcontainerID,
LogSourceID: agentsdk.ExternalLogSourceID,
RunOnStart: true,
Script: "echo this-will-be-replaced",
DisplayName: "Dev Container (test)",
},
},
}
//nolint:dogsled
conn, _, _, _, _ := setupAgent(t, manifest, 0, func(_ *agenttest.Client, o *agent.Options) {
o.ExperimentalDevcontainersEnabled = true
})
t.Logf("Waiting for container with label: devcontainer.local_folder=%s", tempWorkspaceFolder)
var container docker.APIContainers
require.Eventually(t, func() bool {
containers, err := pool.Client.ListContainers(docker.ListContainersOptions{All: true})
if err != nil {
t.Logf("Error listing containers: %v", err)
return false
}
for _, c := range containers {
t.Logf("Found container: %s with labels: %v", c.ID[:12], c.Labels)
if labelValue, ok := c.Labels["devcontainer.local_folder"]; ok {
if labelValue == tempWorkspaceFolder {
t.Logf("Found matching container: %s", c.ID[:12])
container = c
return true
}
}
}
return false
}, testutil.WaitSuperLong, testutil.IntervalMedium, "no container with workspace folder label found")
defer func() {
// We can't rely on pool here because the container is not
// managed by it (it is managed by @devcontainer/cli).
err := pool.Client.RemoveContainer(docker.RemoveContainerOptions{
ID: container.ID,
RemoveVolumes: true,
Force: true,
})
assert.NoError(t, err, "remove container")
}()
containerInfo, err := pool.Client.InspectContainer(container.ID)
require.NoError(t, err, "inspect container")
t.Logf("Container state: status: %v", containerInfo.State.Status)
require.True(t, containerInfo.State.Running, "container should be running")
ctx := testutil.Context(t, testutil.WaitLong)
ac, err := conn.ReconnectingPTY(ctx, uuid.New(), 80, 80, "", func(opts *workspacesdk.AgentReconnectingPTYInit) {
opts.Container = container.ID
})
require.NoError(t, err, "failed to create ReconnectingPTY")
defer ac.Close()
// Use terminal reader so we can see output in case somethin goes wrong.
tr := testutil.NewTerminalReader(t, ac)
require.NoError(t, tr.ReadUntil(ctx, func(line string) bool {
return strings.Contains(line, "#") || strings.Contains(line, "$")
}), "find prompt")
wantFileName := "file-from-devcontainer"
wantFile := filepath.Join(tempWorkspaceFolder, wantFileName)
require.NoError(t, json.NewEncoder(ac).Encode(workspacesdk.ReconnectingPTYRequest{
// NOTE(mafredri): We must use absolute path here for some reason.
Data: fmt.Sprintf("touch /workspaces/mywork/%s; exit\r", wantFileName),
}), "create file inside devcontainer")
// Wait for the connection to close to ensure the touch was executed.
require.ErrorIs(t, tr.ReadUntil(ctx, nil), io.EOF)
_, err = os.Stat(wantFile)
require.NoError(t, err, "file should exist outside devcontainer")
}
// TestAgent_DevcontainerRecreate tests that RecreateDevcontainer
// recreates a devcontainer and emits logs.
//
// This tests end-to-end functionality of auto-starting a devcontainer.
// It runs "devcontainer up" which creates a real Docker container. As
// such, it does not run by default in CI.
//
// You can run it manually as follows:
//
// CODER_TEST_USE_DOCKER=1 go test -count=1 ./agent -run TestAgent_DevcontainerRecreate
func TestAgent_DevcontainerRecreate(t *testing.T) {
if os.Getenv("CODER_TEST_USE_DOCKER") != "1" {
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
}
t.Parallel()
pool, err := dockertest.NewPool("")
require.NoError(t, err, "Could not connect to docker")
// Prepare temporary devcontainer for test (mywork).
devcontainerID := uuid.New()
devcontainerLogSourceID := uuid.New()
workspaceFolder := filepath.Join(t.TempDir(), "mywork")
t.Logf("Workspace folder: %s", workspaceFolder)
devcontainerPath := filepath.Join(workspaceFolder, ".devcontainer")
err = os.MkdirAll(devcontainerPath, 0o755)
require.NoError(t, err, "create devcontainer directory")
devcontainerFile := filepath.Join(devcontainerPath, "devcontainer.json")
err = os.WriteFile(devcontainerFile, []byte(`{
"name": "mywork",
"image": "busybox:latest",
"cmd": ["sleep", "infinity"]
}`), 0o600)
require.NoError(t, err, "write devcontainer.json")
manifest := agentsdk.Manifest{
// Set up pre-conditions for auto-starting a devcontainer, the
// script is used to extract the log source ID.
Devcontainers: []codersdk.WorkspaceAgentDevcontainer{
{
ID: devcontainerID,
Name: "test",
WorkspaceFolder: workspaceFolder,
},
},
Scripts: []codersdk.WorkspaceAgentScript{
{
ID: devcontainerID,
LogSourceID: devcontainerLogSourceID,
},
},
}
//nolint:dogsled
conn, client, _, _, _ := setupAgent(t, manifest, 0, func(_ *agenttest.Client, o *agent.Options) {
o.ExperimentalDevcontainersEnabled = true
})
ctx := testutil.Context(t, testutil.WaitLong)
// We enabled autostart for the devcontainer, so ready is a good
// indication that the devcontainer is up and running. Importantly,
// this also means that the devcontainer startup is no longer
// producing logs that may interfere with the recreate logs.
testutil.Eventually(ctx, t, func(context.Context) bool {
states := client.GetLifecycleStates()
return slices.Contains(states, codersdk.WorkspaceAgentLifecycleReady)
}, testutil.IntervalMedium, "devcontainer not ready")
t.Logf("Looking for container with label: devcontainer.local_folder=%s", workspaceFolder)
var container codersdk.WorkspaceAgentContainer
testutil.Eventually(ctx, t, func(context.Context) bool {
resp, err := conn.ListContainers(ctx)
if err != nil {
t.Logf("Error listing containers: %v", err)
return false
}
for _, c := range resp.Containers {
t.Logf("Found container: %s with labels: %v", c.ID[:12], c.Labels)
if v, ok := c.Labels["devcontainer.local_folder"]; ok && v == workspaceFolder {
t.Logf("Found matching container: %s", c.ID[:12])
container = c
return true
}
}
return false
}, testutil.IntervalMedium, "no container with workspace folder label found")
defer func(container codersdk.WorkspaceAgentContainer) {
// We can't rely on pool here because the container is not
// managed by it (it is managed by @devcontainer/cli).
err := pool.Client.RemoveContainer(docker.RemoveContainerOptions{
ID: container.ID,
RemoveVolumes: true,
Force: true,
})
assert.Error(t, err, "container should be removed by recreate")
}(container)
ctx = testutil.Context(t, testutil.WaitLong) // Reset context.
// Capture logs via ScriptLogger.
logsCh := make(chan *proto.BatchCreateLogsRequest, 1)
client.SetLogsChannel(logsCh)
// Invoke recreate to trigger the destruction and recreation of the
// devcontainer, we do it in a goroutine so we can process logs
// concurrently.
go func(container codersdk.WorkspaceAgentContainer) {
_, err := conn.RecreateDevcontainer(ctx, container.ID)
assert.NoError(t, err, "recreate devcontainer should succeed")
}(container)
t.Logf("Checking recreate logs for outcome...")
// Wait for the logs to be emitted, the @devcontainer/cli up command
// will emit a log with the outcome at the end suggesting we did
// receive all the logs.
waitForOutcomeLoop:
for {
batch := testutil.RequireReceive(ctx, t, logsCh)
if bytes.Equal(batch.LogSourceId, devcontainerLogSourceID[:]) {
for _, log := range batch.Logs {
t.Logf("Received log: %s", log.Output)
if strings.Contains(log.Output, "\"outcome\"") {
break waitForOutcomeLoop
}
}
}
}
t.Logf("Checking there's a new container with label: devcontainer.local_folder=%s", workspaceFolder)
// Make sure the container exists and isn't the same as the old one.
testutil.Eventually(ctx, t, func(context.Context) bool {
resp, err := conn.ListContainers(ctx)
if err != nil {
t.Logf("Error listing containers: %v", err)
return false
}
for _, c := range resp.Containers {
t.Logf("Found container: %s with labels: %v", c.ID[:12], c.Labels)
if v, ok := c.Labels["devcontainer.local_folder"]; ok && v == workspaceFolder {
if c.ID == container.ID {
t.Logf("Found same container: %s", c.ID[:12])
return false
}
t.Logf("Found new container: %s", c.ID[:12])
container = c
return true
}
}
return false
}, testutil.IntervalMedium, "new devcontainer not found")
defer func(container codersdk.WorkspaceAgentContainer) {
// We can't rely on pool here because the container is not
// managed by it (it is managed by @devcontainer/cli).
err := pool.Client.RemoveContainer(docker.RemoveContainerOptions{
ID: container.ID,
RemoveVolumes: true,
Force: true,
})
assert.NoError(t, err, "remove container")
}(container)
}
func TestAgent_Dial(t *testing.T) {
t.Parallel()
@@ -2304,7 +2797,7 @@ done
n := 1
for n <= 5 {
logs := testutil.RequireRecvCtx(ctx, t, logsCh)
logs := testutil.TryReceive(ctx, t, logsCh)
require.NotNil(t, logs)
for _, l := range logs.GetLogs() {
require.Equal(t, fmt.Sprintf("start %d", n), l.GetOutput())
@@ -2317,7 +2810,7 @@ done
n = 1
for n <= 3000 {
logs := testutil.RequireRecvCtx(ctx, t, logsCh)
logs := testutil.TryReceive(ctx, t, logsCh)
require.NotNil(t, logs)
for _, l := range logs.GetLogs() {
require.Equal(t, fmt.Sprintf("stop %d", n), l.GetOutput())
@@ -2732,3 +3225,35 @@ func requireEcho(t *testing.T, conn net.Conn) {
require.NoError(t, err)
require.Equal(t, "test", string(b))
}
func assertConnectionReport(t testing.TB, agentClient *agenttest.Client, connectionType proto.Connection_Type, status int, reason string) {
t.Helper()
var reports []*proto.ReportConnectionRequest
if !assert.Eventually(t, func() bool {
reports = agentClient.GetConnectionReports()
return len(reports) >= 2
}, testutil.WaitMedium, testutil.IntervalFast, "waiting for 2 connection reports or more; got %d", len(reports)) {
return
}
assert.Len(t, reports, 2, "want 2 connection reports")
assert.Equal(t, proto.Connection_CONNECT, reports[0].GetConnection().GetAction(), "first report should be connect")
assert.Equal(t, proto.Connection_DISCONNECT, reports[1].GetConnection().GetAction(), "second report should be disconnect")
assert.Equal(t, connectionType, reports[0].GetConnection().GetType(), "connect type should be %s", connectionType)
assert.Equal(t, connectionType, reports[1].GetConnection().GetType(), "disconnect type should be %s", connectionType)
t1 := reports[0].GetConnection().GetTimestamp().AsTime()
t2 := reports[1].GetConnection().GetTimestamp().AsTime()
assert.True(t, t1.Before(t2) || t1.Equal(t2), "connect timestamp should be before or equal to disconnect timestamp")
assert.NotEmpty(t, reports[0].GetConnection().GetIp(), "connect ip should not be empty")
assert.NotEmpty(t, reports[1].GetConnection().GetIp(), "disconnect ip should not be empty")
assert.Equal(t, 0, int(reports[0].GetConnection().GetStatusCode()), "connect status code should be 0")
assert.Equal(t, status, int(reports[1].GetConnection().GetStatusCode()), "disconnect status code should be %d", status)
assert.Equal(t, "", reports[0].GetConnection().GetReason(), "connect reason should be empty")
if reason != "" {
assert.Contains(t, reports[1].GetConnection().GetReason(), reason, "disconnect reason should contain %s", reason)
} else {
t.Logf("connection report disconnect reason: %s", reports[1].GetConnection().GetReason())
}
}
+47 -2
View File
@@ -1,9 +1,9 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: .. (interfaces: Lister)
// Source: .. (interfaces: Lister,DevcontainerCLI)
//
// Generated by this command:
//
// mockgen -destination ./acmock.go -package acmock .. Lister
// mockgen -destination ./acmock.go -package acmock .. Lister,DevcontainerCLI
//
// Package acmock is a generated GoMock package.
@@ -13,6 +13,7 @@ import (
context "context"
reflect "reflect"
agentcontainers "github.com/coder/coder/v2/agent/agentcontainers"
codersdk "github.com/coder/coder/v2/codersdk"
gomock "go.uber.org/mock/gomock"
)
@@ -55,3 +56,47 @@ func (mr *MockListerMockRecorder) List(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockLister)(nil).List), ctx)
}
// MockDevcontainerCLI is a mock of DevcontainerCLI interface.
type MockDevcontainerCLI struct {
ctrl *gomock.Controller
recorder *MockDevcontainerCLIMockRecorder
isgomock struct{}
}
// MockDevcontainerCLIMockRecorder is the mock recorder for MockDevcontainerCLI.
type MockDevcontainerCLIMockRecorder struct {
mock *MockDevcontainerCLI
}
// NewMockDevcontainerCLI creates a new mock instance.
func NewMockDevcontainerCLI(ctrl *gomock.Controller) *MockDevcontainerCLI {
mock := &MockDevcontainerCLI{ctrl: ctrl}
mock.recorder = &MockDevcontainerCLIMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockDevcontainerCLI) EXPECT() *MockDevcontainerCLIMockRecorder {
return m.recorder
}
// Up mocks base method.
func (m *MockDevcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath string, opts ...agentcontainers.DevcontainerCLIUpOptions) (string, error) {
m.ctrl.T.Helper()
varargs := []any{ctx, workspaceFolder, configPath}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "Up", varargs...)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Up indicates an expected call of Up.
func (mr *MockDevcontainerCLIMockRecorder) Up(ctx, workspaceFolder, configPath any, opts ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{ctx, workspaceFolder, configPath}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Up", reflect.TypeOf((*MockDevcontainerCLI)(nil).Up), varargs...)
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Package acmock contains a mock implementation of agentcontainers.Lister for use in tests.
package acmock
//go:generate mockgen -destination ./acmock.go -package acmock .. Lister
//go:generate mockgen -destination ./acmock.go -package acmock .. Lister,DevcontainerCLI
+827
View File
@@ -0,0 +1,827 @@
package agentcontainers
import (
"context"
"errors"
"fmt"
"net/http"
"path"
"slices"
"strings"
"sync"
"time"
"github.com/fsnotify/fsnotify"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"golang.org/x/xerrors"
"cdr.dev/slog"
"github.com/coder/coder/v2/agent/agentcontainers/watcher"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/quartz"
)
const (
defaultUpdateInterval = 10 * time.Second
listContainersTimeout = 15 * time.Second
)
// API is responsible for container-related operations in the agent.
// It provides methods to list and manage containers.
type API struct {
ctx context.Context
cancel context.CancelFunc
watcherDone chan struct{}
updaterDone chan struct{}
initialUpdateDone chan struct{} // Closed after first update in updaterLoop.
updateTrigger chan chan error // Channel to trigger manual refresh.
updateInterval time.Duration // Interval for periodic container updates.
logger slog.Logger
watcher watcher.Watcher
execer agentexec.Execer
cl Lister
dccli DevcontainerCLI
clock quartz.Clock
scriptLogger func(logSourceID uuid.UUID) ScriptLogger
mu sync.RWMutex
closed bool
containers codersdk.WorkspaceAgentListContainersResponse // Output from the last list operation.
containersErr error // Error from the last list operation.
devcontainerNames map[string]bool // By devcontainer name.
knownDevcontainers map[string]codersdk.WorkspaceAgentDevcontainer // By workspace folder.
configFileModifiedTimes map[string]time.Time // By config file path.
recreateSuccessTimes map[string]time.Time // By workspace folder.
recreateErrorTimes map[string]time.Time // By workspace folder.
recreateWg sync.WaitGroup
devcontainerLogSourceIDs map[string]uuid.UUID // By workspace folder.
}
// Option is a functional option for API.
type Option func(*API)
// WithClock sets the quartz.Clock implementation to use.
// This is primarily used for testing to control time.
func WithClock(clock quartz.Clock) Option {
return func(api *API) {
api.clock = clock
}
}
// WithExecer sets the agentexec.Execer implementation to use.
func WithExecer(execer agentexec.Execer) Option {
return func(api *API) {
api.execer = execer
}
}
// WithLister sets the agentcontainers.Lister implementation to use.
// The default implementation uses the Docker CLI to list containers.
func WithLister(cl Lister) Option {
return func(api *API) {
api.cl = cl
}
}
// WithDevcontainerCLI sets the DevcontainerCLI implementation to use.
// This can be used in tests to modify @devcontainer/cli behavior.
func WithDevcontainerCLI(dccli DevcontainerCLI) Option {
return func(api *API) {
api.dccli = dccli
}
}
// WithDevcontainers sets the known devcontainers for the API. This
// allows the API to be aware of devcontainers defined in the workspace
// agent manifest.
func WithDevcontainers(devcontainers []codersdk.WorkspaceAgentDevcontainer, scripts []codersdk.WorkspaceAgentScript) Option {
return func(api *API) {
if len(devcontainers) == 0 {
return
}
api.knownDevcontainers = make(map[string]codersdk.WorkspaceAgentDevcontainer, len(devcontainers))
api.devcontainerNames = make(map[string]bool, len(devcontainers))
api.devcontainerLogSourceIDs = make(map[string]uuid.UUID)
for _, dc := range devcontainers {
api.knownDevcontainers[dc.WorkspaceFolder] = dc
api.devcontainerNames[dc.Name] = true
for _, script := range scripts {
// The devcontainer scripts match the devcontainer ID for
// identification.
if script.ID == dc.ID {
api.devcontainerLogSourceIDs[dc.WorkspaceFolder] = script.LogSourceID
break
}
}
if api.devcontainerLogSourceIDs[dc.WorkspaceFolder] == uuid.Nil {
api.logger.Error(api.ctx, "devcontainer log source ID not found for devcontainer",
slog.F("devcontainer_id", dc.ID),
slog.F("devcontainer_name", dc.Name),
slog.F("workspace_folder", dc.WorkspaceFolder),
slog.F("config_path", dc.ConfigPath),
)
}
}
}
}
// WithWatcher sets the file watcher implementation to use. By default a
// noop watcher is used. This can be used in tests to modify the watcher
// behavior or to use an actual file watcher (e.g. fsnotify).
func WithWatcher(w watcher.Watcher) Option {
return func(api *API) {
api.watcher = w
}
}
// ScriptLogger is an interface for sending devcontainer logs to the
// controlplane.
type ScriptLogger interface {
Send(ctx context.Context, log ...agentsdk.Log) error
Flush(ctx context.Context) error
}
// noopScriptLogger is a no-op implementation of the ScriptLogger
// interface.
type noopScriptLogger struct{}
func (noopScriptLogger) Send(context.Context, ...agentsdk.Log) error { return nil }
func (noopScriptLogger) Flush(context.Context) error { return nil }
// WithScriptLogger sets the script logger provider for devcontainer operations.
func WithScriptLogger(scriptLogger func(logSourceID uuid.UUID) ScriptLogger) Option {
return func(api *API) {
api.scriptLogger = scriptLogger
}
}
// NewAPI returns a new API with the given options applied.
func NewAPI(logger slog.Logger, options ...Option) *API {
ctx, cancel := context.WithCancel(context.Background())
api := &API{
ctx: ctx,
cancel: cancel,
watcherDone: make(chan struct{}),
updaterDone: make(chan struct{}),
initialUpdateDone: make(chan struct{}),
updateTrigger: make(chan chan error),
updateInterval: defaultUpdateInterval,
logger: logger,
clock: quartz.NewReal(),
execer: agentexec.DefaultExecer,
devcontainerNames: make(map[string]bool),
knownDevcontainers: make(map[string]codersdk.WorkspaceAgentDevcontainer),
configFileModifiedTimes: make(map[string]time.Time),
recreateSuccessTimes: make(map[string]time.Time),
recreateErrorTimes: make(map[string]time.Time),
scriptLogger: func(uuid.UUID) ScriptLogger { return noopScriptLogger{} },
}
// The ctx and logger must be set before applying options to avoid
// nil pointer dereference.
for _, opt := range options {
opt(api)
}
if api.cl == nil {
api.cl = NewDocker(api.execer)
}
if api.dccli == nil {
api.dccli = NewDevcontainerCLI(logger.Named("devcontainer-cli"), api.execer)
}
if api.watcher == nil {
var err error
api.watcher, err = watcher.NewFSNotify()
if err != nil {
logger.Error(ctx, "create file watcher service failed", slog.Error(err))
api.watcher = watcher.NewNoop()
}
}
go api.watcherLoop()
go api.updaterLoop()
return api
}
func (api *API) watcherLoop() {
defer close(api.watcherDone)
defer api.logger.Debug(api.ctx, "watcher loop stopped")
api.logger.Debug(api.ctx, "watcher loop started")
for {
event, err := api.watcher.Next(api.ctx)
if err != nil {
if errors.Is(err, watcher.ErrClosed) {
api.logger.Debug(api.ctx, "watcher closed")
return
}
if api.ctx.Err() != nil {
api.logger.Debug(api.ctx, "api context canceled")
return
}
api.logger.Error(api.ctx, "watcher error waiting for next event", slog.Error(err))
continue
}
if event == nil {
continue
}
now := api.clock.Now("watcherLoop")
switch {
case event.Has(fsnotify.Create | fsnotify.Write):
api.logger.Debug(api.ctx, "devcontainer config file changed", slog.F("file", event.Name))
api.markDevcontainerDirty(event.Name, now)
case event.Has(fsnotify.Remove):
api.logger.Debug(api.ctx, "devcontainer config file removed", slog.F("file", event.Name))
api.markDevcontainerDirty(event.Name, now)
case event.Has(fsnotify.Rename):
api.logger.Debug(api.ctx, "devcontainer config file renamed", slog.F("file", event.Name))
api.markDevcontainerDirty(event.Name, now)
default:
api.logger.Debug(api.ctx, "devcontainer config file event ignored", slog.F("file", event.Name), slog.F("event", event))
}
}
}
// updaterLoop is responsible for periodically updating the container
// list and handling manual refresh requests.
func (api *API) updaterLoop() {
defer close(api.updaterDone)
defer api.logger.Debug(api.ctx, "updater loop stopped")
api.logger.Debug(api.ctx, "updater loop started")
// Perform an initial update to populate the container list, this
// gives us a guarantee that the API has loaded the initial state
// before returning any responses. This is useful for both tests
// and anyone looking to interact with the API.
api.logger.Debug(api.ctx, "performing initial containers update")
if err := api.updateContainers(api.ctx); err != nil {
api.logger.Error(api.ctx, "initial containers update failed", slog.Error(err))
} else {
api.logger.Debug(api.ctx, "initial containers update complete")
}
// Signal that the initial update attempt (successful or not) is done.
// Other services can wait on this if they need the first data to be available.
close(api.initialUpdateDone)
// We utilize a TickerFunc here instead of a regular Ticker so that
// we can guarantee execution of the updateContainers method after
// advancing the clock.
ticker := api.clock.TickerFunc(api.ctx, api.updateInterval, func() error {
done := make(chan error, 1)
defer close(done)
select {
case <-api.ctx.Done():
return api.ctx.Err()
case api.updateTrigger <- done:
err := <-done
if err != nil {
api.logger.Error(api.ctx, "updater loop ticker failed", slog.Error(err))
}
default:
api.logger.Debug(api.ctx, "updater loop ticker skipped, update in progress")
}
return nil // Always nil to keep the ticker going.
}, "updaterLoop")
defer func() {
if err := ticker.Wait("updaterLoop"); err != nil && !errors.Is(err, context.Canceled) {
api.logger.Error(api.ctx, "updater loop ticker failed", slog.Error(err))
}
}()
for {
select {
case <-api.ctx.Done():
return
case done := <-api.updateTrigger:
// Note that although we pass api.ctx here, updateContainers
// has an internal timeout to prevent long blocking calls.
done <- api.updateContainers(api.ctx)
}
}
}
// Routes returns the HTTP handler for container-related routes.
func (api *API) Routes() http.Handler {
r := chi.NewRouter()
ensureInitialUpdateDoneMW := func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
select {
case <-api.ctx.Done():
httpapi.Write(r.Context(), rw, http.StatusServiceUnavailable, codersdk.Response{
Message: "API closed",
Detail: "The API is closed and cannot process requests.",
})
return
case <-r.Context().Done():
return
case <-api.initialUpdateDone:
// Initial update is done, we can start processing
// requests.
}
next.ServeHTTP(rw, r)
})
}
// For now, all endpoints require the initial update to be done.
// If we want to allow some endpoints to be available before
// the initial update, we can enable this per-route.
r.Use(ensureInitialUpdateDoneMW)
r.Get("/", api.handleList)
r.Route("/devcontainers", func(r chi.Router) {
r.Get("/", api.handleDevcontainersList)
r.Post("/container/{container}/recreate", api.handleDevcontainerRecreate)
})
return r
}
// handleList handles the HTTP request to list containers.
func (api *API) handleList(rw http.ResponseWriter, r *http.Request) {
ct, err := api.getContainers()
if err != nil {
httpapi.Write(r.Context(), rw, http.StatusInternalServerError, codersdk.Response{
Message: "Could not get containers",
Detail: err.Error(),
})
return
}
httpapi.Write(r.Context(), rw, http.StatusOK, ct)
}
// updateContainers fetches the latest container list, processes it, and
// updates the cache. It performs locking for updating shared API state.
func (api *API) updateContainers(ctx context.Context) error {
listCtx, listCancel := context.WithTimeout(ctx, listContainersTimeout)
defer listCancel()
updated, err := api.cl.List(listCtx)
if err != nil {
// If the context was canceled, we hold off on clearing the
// containers cache. This is to avoid clearing the cache if
// the update was canceled due to a timeout. Hopefully this
// will clear up on the next update.
if !errors.Is(err, context.Canceled) {
api.mu.Lock()
api.containers = codersdk.WorkspaceAgentListContainersResponse{}
api.containersErr = err
api.mu.Unlock()
}
return xerrors.Errorf("list containers failed: %w", err)
}
api.mu.Lock()
defer api.mu.Unlock()
api.processUpdatedContainersLocked(ctx, updated)
api.logger.Debug(ctx, "containers updated successfully", slog.F("container_count", len(api.containers.Containers)), slog.F("warning_count", len(api.containers.Warnings)), slog.F("devcontainer_count", len(api.knownDevcontainers)))
return nil
}
// processUpdatedContainersLocked updates the devcontainer state based
// on the latest list of containers. This method assumes that api.mu is
// held.
func (api *API) processUpdatedContainersLocked(ctx context.Context, updated codersdk.WorkspaceAgentListContainersResponse) {
// Reset the container links in known devcontainers to detect if
// they still exist.
for _, dc := range api.knownDevcontainers {
dc.Container = nil
api.knownDevcontainers[dc.WorkspaceFolder] = dc
}
// Check if the container is running and update the known devcontainers.
for i := range updated.Containers {
container := &updated.Containers[i] // Grab a reference to the container to allow mutating it.
container.DevcontainerStatus = "" // Reset the status for the container (updated later).
container.DevcontainerDirty = false // Reset dirty state for the container (updated later).
workspaceFolder := container.Labels[DevcontainerLocalFolderLabel]
configFile := container.Labels[DevcontainerConfigFileLabel]
if workspaceFolder == "" {
continue
}
if dc, ok := api.knownDevcontainers[workspaceFolder]; ok {
// If no config path is set, this devcontainer was defined
// in Terraform without the optional config file. Assume the
// first container with the workspace folder label is the
// one we want to use.
if dc.ConfigPath == "" && configFile != "" {
dc.ConfigPath = configFile
if err := api.watcher.Add(configFile); err != nil {
api.logger.Error(ctx, "watch devcontainer config file failed", slog.Error(err), slog.F("file", configFile))
}
}
dc.Container = container
api.knownDevcontainers[dc.WorkspaceFolder] = dc
continue
}
// NOTE(mafredri): This name impl. may change to accommodate devcontainer agents RFC.
// If not in our known list, add as a runtime detected entry.
name := path.Base(workspaceFolder)
if api.devcontainerNames[name] {
// Try to find a unique name by appending a number.
for i := 2; ; i++ {
newName := fmt.Sprintf("%s-%d", name, i)
if !api.devcontainerNames[newName] {
name = newName
break
}
}
}
api.devcontainerNames[name] = true
if configFile != "" {
if err := api.watcher.Add(configFile); err != nil {
api.logger.Error(ctx, "watch devcontainer config file failed", slog.Error(err), slog.F("file", configFile))
}
}
api.knownDevcontainers[workspaceFolder] = codersdk.WorkspaceAgentDevcontainer{
ID: uuid.New(),
Name: name,
WorkspaceFolder: workspaceFolder,
ConfigPath: configFile,
Status: "", // Updated later based on container state.
Dirty: false, // Updated later based on config file changes.
Container: container,
}
}
// Iterate through all known devcontainers and update their status
// based on the current state of the containers.
for _, dc := range api.knownDevcontainers {
switch {
case dc.Status == codersdk.WorkspaceAgentDevcontainerStatusStarting:
if dc.Container != nil {
dc.Container.DevcontainerStatus = dc.Status
dc.Container.DevcontainerDirty = dc.Dirty
}
continue // This state is handled by the recreation routine.
case dc.Status == codersdk.WorkspaceAgentDevcontainerStatusError && (dc.Container == nil || dc.Container.CreatedAt.Before(api.recreateErrorTimes[dc.WorkspaceFolder])):
if dc.Container != nil {
dc.Container.DevcontainerStatus = dc.Status
dc.Container.DevcontainerDirty = dc.Dirty
}
continue // The devcontainer needs to be recreated.
case dc.Container != nil:
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStopped
if dc.Container.Running {
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusRunning
}
dc.Container.DevcontainerStatus = dc.Status
dc.Dirty = false
if lastModified, hasModTime := api.configFileModifiedTimes[dc.ConfigPath]; hasModTime && dc.Container.CreatedAt.Before(lastModified) {
dc.Dirty = true
}
dc.Container.DevcontainerDirty = dc.Dirty
case dc.Container == nil:
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStopped
dc.Dirty = false
}
delete(api.recreateErrorTimes, dc.WorkspaceFolder)
api.knownDevcontainers[dc.WorkspaceFolder] = dc
}
api.containers = updated
api.containersErr = nil
}
// refreshContainers triggers an immediate update of the container list
// and waits for it to complete.
func (api *API) refreshContainers(ctx context.Context) (err error) {
defer func() {
if err != nil {
err = xerrors.Errorf("refresh containers failed: %w", err)
}
}()
done := make(chan error, 1)
select {
case <-api.ctx.Done():
return xerrors.Errorf("API closed: %w", api.ctx.Err())
case <-ctx.Done():
return ctx.Err()
case api.updateTrigger <- done:
select {
case <-api.ctx.Done():
return xerrors.Errorf("API closed: %w", api.ctx.Err())
case <-ctx.Done():
return ctx.Err()
case err := <-done:
return err
}
}
}
func (api *API) getContainers() (codersdk.WorkspaceAgentListContainersResponse, error) {
api.mu.RLock()
defer api.mu.RUnlock()
if api.containersErr != nil {
return codersdk.WorkspaceAgentListContainersResponse{}, api.containersErr
}
return codersdk.WorkspaceAgentListContainersResponse{
Containers: slices.Clone(api.containers.Containers),
Warnings: slices.Clone(api.containers.Warnings),
}, nil
}
// handleDevcontainerRecreate handles the HTTP request to recreate a
// devcontainer by referencing the container.
func (api *API) handleDevcontainerRecreate(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
containerID := chi.URLParam(r, "container")
if containerID == "" {
httpapi.Write(ctx, w, http.StatusBadRequest, codersdk.Response{
Message: "Missing container ID or name",
Detail: "Container ID or name is required to recreate a devcontainer.",
})
return
}
containers, err := api.getContainers()
if err != nil {
httpapi.Write(ctx, w, http.StatusInternalServerError, codersdk.Response{
Message: "Could not list containers",
Detail: err.Error(),
})
return
}
containerIdx := slices.IndexFunc(containers.Containers, func(c codersdk.WorkspaceAgentContainer) bool { return c.Match(containerID) })
if containerIdx == -1 {
httpapi.Write(ctx, w, http.StatusNotFound, codersdk.Response{
Message: "Container not found",
Detail: "Container ID or name not found in the list of containers.",
})
return
}
container := containers.Containers[containerIdx]
workspaceFolder := container.Labels[DevcontainerLocalFolderLabel]
configPath := container.Labels[DevcontainerConfigFileLabel]
// Workspace folder is required to recreate a container, we don't verify
// the config path here because it's optional.
if workspaceFolder == "" {
httpapi.Write(ctx, w, http.StatusBadRequest, codersdk.Response{
Message: "Missing workspace folder label",
Detail: "The container is not a devcontainer, the container must have the workspace folder label to support recreation.",
})
return
}
api.mu.Lock()
dc, ok := api.knownDevcontainers[workspaceFolder]
switch {
case !ok:
api.mu.Unlock()
// This case should not happen if the container is a valid devcontainer.
api.logger.Error(ctx, "devcontainer not found for workspace folder", slog.F("workspace_folder", workspaceFolder))
httpapi.Write(ctx, w, http.StatusInternalServerError, codersdk.Response{
Message: "Devcontainer not found.",
Detail: fmt.Sprintf("Could not find devcontainer for workspace folder: %q", workspaceFolder),
})
return
case dc.Status == codersdk.WorkspaceAgentDevcontainerStatusStarting:
api.mu.Unlock()
httpapi.Write(ctx, w, http.StatusConflict, codersdk.Response{
Message: "Devcontainer recreation already in progress",
Detail: fmt.Sprintf("Recreation for workspace folder %q is already underway.", dc.WorkspaceFolder),
})
return
}
// Update the status so that we don't try to recreate the
// devcontainer multiple times in parallel.
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStarting
if dc.Container != nil {
dc.Container.DevcontainerStatus = dc.Status
}
api.knownDevcontainers[dc.WorkspaceFolder] = dc
api.recreateWg.Add(1)
go api.recreateDevcontainer(dc, configPath)
api.mu.Unlock()
httpapi.Write(ctx, w, http.StatusAccepted, codersdk.Response{
Message: "Devcontainer recreation initiated",
Detail: fmt.Sprintf("Recreation process for workspace folder %q has started.", dc.WorkspaceFolder),
})
}
// recreateDevcontainer should run in its own goroutine and is responsible for
// recreating a devcontainer based on the provided devcontainer configuration.
// It updates the devcontainer status and logs the process. The configPath is
// passed as a parameter for the odd chance that the container being recreated
// has a different config file than the one stored in the devcontainer state.
// The devcontainer state must be set to starting and the recreateWg must be
// incremented before calling this function.
func (api *API) recreateDevcontainer(dc codersdk.WorkspaceAgentDevcontainer, configPath string) {
defer api.recreateWg.Done()
var (
err error
ctx = api.ctx
logger = api.logger.With(
slog.F("devcontainer_id", dc.ID),
slog.F("devcontainer_name", dc.Name),
slog.F("workspace_folder", dc.WorkspaceFolder),
slog.F("config_path", configPath),
)
)
if dc.ConfigPath != configPath {
logger.Warn(ctx, "devcontainer config path mismatch",
slog.F("config_path_param", configPath),
)
}
// Send logs via agent logging facilities.
logSourceID := api.devcontainerLogSourceIDs[dc.WorkspaceFolder]
if logSourceID == uuid.Nil {
// Fallback to the external log source ID if not found.
logSourceID = agentsdk.ExternalLogSourceID
}
scriptLogger := api.scriptLogger(logSourceID)
defer func() {
flushCtx, cancel := context.WithTimeout(api.ctx, 5*time.Second)
defer cancel()
if err := scriptLogger.Flush(flushCtx); err != nil {
logger.Error(flushCtx, "flush devcontainer logs failed during recreation", slog.Error(err))
}
}()
infoW := agentsdk.LogsWriter(ctx, scriptLogger.Send, logSourceID, codersdk.LogLevelInfo)
defer infoW.Close()
errW := agentsdk.LogsWriter(ctx, scriptLogger.Send, logSourceID, codersdk.LogLevelError)
defer errW.Close()
logger.Debug(ctx, "starting devcontainer recreation")
_, err = api.dccli.Up(ctx, dc.WorkspaceFolder, configPath, WithOutput(infoW, errW), WithRemoveExistingContainer())
if err != nil {
// No need to log if the API is closing (context canceled), as this
// is expected behavior when the API is shutting down.
if !errors.Is(err, context.Canceled) {
logger.Error(ctx, "devcontainer recreation failed", slog.Error(err))
}
api.mu.Lock()
dc = api.knownDevcontainers[dc.WorkspaceFolder]
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusError
if dc.Container != nil {
dc.Container.DevcontainerStatus = dc.Status
}
api.knownDevcontainers[dc.WorkspaceFolder] = dc
api.recreateErrorTimes[dc.WorkspaceFolder] = api.clock.Now("recreate", "errorTimes")
api.mu.Unlock()
return
}
logger.Info(ctx, "devcontainer recreated successfully")
api.mu.Lock()
dc = api.knownDevcontainers[dc.WorkspaceFolder]
// Update the devcontainer status to Running or Stopped based on the
// current state of the container, changing the status to !starting
// allows the update routine to update the devcontainer status, but
// to minimize the time between API consistency, we guess the status
// based on the container state.
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStopped
if dc.Container != nil {
if dc.Container.Running {
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusRunning
}
dc.Container.DevcontainerStatus = dc.Status
}
dc.Dirty = false
api.recreateSuccessTimes[dc.WorkspaceFolder] = api.clock.Now("recreate", "successTimes")
api.knownDevcontainers[dc.WorkspaceFolder] = dc
api.mu.Unlock()
// Ensure an immediate refresh to accurately reflect the
// devcontainer state after recreation.
if err := api.refreshContainers(ctx); err != nil {
logger.Error(ctx, "failed to trigger immediate refresh after devcontainer recreation", slog.Error(err))
}
}
// handleDevcontainersList handles the HTTP request to list known devcontainers.
func (api *API) handleDevcontainersList(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
api.mu.RLock()
err := api.containersErr
devcontainers := make([]codersdk.WorkspaceAgentDevcontainer, 0, len(api.knownDevcontainers))
for _, dc := range api.knownDevcontainers {
devcontainers = append(devcontainers, dc)
}
api.mu.RUnlock()
if err != nil {
httpapi.Write(ctx, w, http.StatusInternalServerError, codersdk.Response{
Message: "Could not list containers",
Detail: err.Error(),
})
return
}
slices.SortFunc(devcontainers, func(a, b codersdk.WorkspaceAgentDevcontainer) int {
if cmp := strings.Compare(a.WorkspaceFolder, b.WorkspaceFolder); cmp != 0 {
return cmp
}
return strings.Compare(a.ConfigPath, b.ConfigPath)
})
response := codersdk.WorkspaceAgentDevcontainersResponse{
Devcontainers: devcontainers,
}
httpapi.Write(ctx, w, http.StatusOK, response)
}
// markDevcontainerDirty finds the devcontainer with the given config file path
// and marks it as dirty. It acquires the lock before modifying the state.
func (api *API) markDevcontainerDirty(configPath string, modifiedAt time.Time) {
api.mu.Lock()
defer api.mu.Unlock()
// Record the timestamp of when this configuration file was modified.
api.configFileModifiedTimes[configPath] = modifiedAt
for _, dc := range api.knownDevcontainers {
if dc.ConfigPath != configPath {
continue
}
logger := api.logger.With(
slog.F("devcontainer_id", dc.ID),
slog.F("devcontainer_name", dc.Name),
slog.F("workspace_folder", dc.WorkspaceFolder),
slog.F("file", configPath),
slog.F("modified_at", modifiedAt),
)
// TODO(mafredri): Simplistic mark for now, we should check if the
// container is running and if the config file was modified after
// the container was created.
if !dc.Dirty {
logger.Info(api.ctx, "marking devcontainer as dirty")
dc.Dirty = true
}
if dc.Container != nil && !dc.Container.DevcontainerDirty {
logger.Info(api.ctx, "marking devcontainer container as dirty")
dc.Container.DevcontainerDirty = true
}
api.knownDevcontainers[dc.WorkspaceFolder] = dc
}
}
func (api *API) Close() error {
api.mu.Lock()
if api.closed {
api.mu.Unlock()
return nil
}
api.logger.Debug(api.ctx, "closing API")
api.closed = true
api.cancel() // Interrupt all routines.
api.mu.Unlock() // Release lock before waiting for goroutines.
// Close the watcher to ensure its loop finishes.
err := api.watcher.Close()
// Wait for loops to finish.
<-api.watcherDone
<-api.updaterDone
// Wait for all devcontainer recreation tasks to complete.
api.recreateWg.Wait()
api.logger.Debug(api.ctx, "closed API")
return err
}
File diff suppressed because it is too large Load Diff
-127
View File
@@ -2,137 +2,10 @@ package agentcontainers
import (
"context"
"errors"
"net/http"
"slices"
"time"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/quartz"
)
const (
defaultGetContainersCacheDuration = 10 * time.Second
dockerCreatedAtTimeFormat = "2006-01-02 15:04:05 -0700 MST"
getContainersTimeout = 5 * time.Second
)
type devcontainersHandler struct {
cacheDuration time.Duration
cl Lister
clock quartz.Clock
// lockCh protects the below fields. We use a channel instead of a mutex so we
// can handle cancellation properly.
lockCh chan struct{}
containers *codersdk.WorkspaceAgentListContainersResponse
mtime time.Time
}
// Option is a functional option for devcontainersHandler.
type Option func(*devcontainersHandler)
// WithLister sets the agentcontainers.Lister implementation to use.
// The default implementation uses the Docker CLI to list containers.
func WithLister(cl Lister) Option {
return func(ch *devcontainersHandler) {
ch.cl = cl
}
}
// New returns a new devcontainersHandler with the given options applied.
func New(options ...Option) http.Handler {
ch := &devcontainersHandler{
lockCh: make(chan struct{}, 1),
}
for _, opt := range options {
opt(ch)
}
return ch
}
func (ch *devcontainersHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
select {
case <-r.Context().Done():
// Client went away.
return
default:
ct, err := ch.getContainers(r.Context())
if err != nil {
if errors.Is(err, context.Canceled) {
httpapi.Write(r.Context(), rw, http.StatusRequestTimeout, codersdk.Response{
Message: "Could not get containers.",
Detail: "Took too long to list containers.",
})
return
}
httpapi.Write(r.Context(), rw, http.StatusInternalServerError, codersdk.Response{
Message: "Could not get containers.",
Detail: err.Error(),
})
return
}
httpapi.Write(r.Context(), rw, http.StatusOK, ct)
}
}
func (ch *devcontainersHandler) getContainers(ctx context.Context) (codersdk.WorkspaceAgentListContainersResponse, error) {
select {
case <-ctx.Done():
return codersdk.WorkspaceAgentListContainersResponse{}, ctx.Err()
default:
ch.lockCh <- struct{}{}
}
defer func() {
<-ch.lockCh
}()
// make zero-value usable
if ch.cacheDuration == 0 {
ch.cacheDuration = defaultGetContainersCacheDuration
}
if ch.cl == nil {
ch.cl = &DockerCLILister{}
}
if ch.containers == nil {
ch.containers = &codersdk.WorkspaceAgentListContainersResponse{}
}
if ch.clock == nil {
ch.clock = quartz.NewReal()
}
now := ch.clock.Now()
if now.Sub(ch.mtime) < ch.cacheDuration {
// Return a copy of the cached data to avoid accidental modification by the caller.
cpy := codersdk.WorkspaceAgentListContainersResponse{
Containers: slices.Clone(ch.containers.Containers),
Warnings: slices.Clone(ch.containers.Warnings),
}
return cpy, nil
}
timeoutCtx, timeoutCancel := context.WithTimeout(ctx, getContainersTimeout)
defer timeoutCancel()
updated, err := ch.cl.List(timeoutCtx)
if err != nil {
return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("get containers: %w", err)
}
ch.containers = &updated
ch.mtime = now
// Return a copy of the cached data to avoid accidental modification by the
// caller.
cpy := codersdk.WorkspaceAgentListContainersResponse{
Containers: slices.Clone(ch.containers.Containers),
Warnings: slices.Clone(ch.containers.Warnings),
}
return cpy, nil
}
// Lister is an interface for listing containers visible to the
// workspace agent.
type Lister interface {
+195 -124
View File
@@ -6,7 +6,7 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"net"
"os/user"
"slices"
"sort"
@@ -14,29 +14,20 @@ import (
"strings"
"time"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/codersdk"
"golang.org/x/exp/maps"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/agent/agentcontainers/dcspec"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/agent/usershell"
"github.com/coder/coder/v2/coderd/util/ptr"
"github.com/coder/coder/v2/codersdk"
)
// DockerCLILister is a ContainerLister that lists containers using the docker CLI
type DockerCLILister struct {
execer agentexec.Execer
}
var _ Lister = &DockerCLILister{}
func NewDocker(execer agentexec.Execer) Lister {
return &DockerCLILister{
execer: agentexec.DefaultExecer,
}
}
// DockerEnvInfoer is an implementation of agentssh.EnvInfoer that returns
// information about a container.
type DockerEnvInfoer struct {
usershell.SystemEnvInfo
container string
user *user.User
userShell string
@@ -122,26 +113,13 @@ func EnvInfo(ctx context.Context, execer agentexec.Execer, container, containerU
return &dei, nil
}
func (dei *DockerEnvInfoer) CurrentUser() (*user.User, error) {
func (dei *DockerEnvInfoer) User() (*user.User, error) {
// Clone the user so that the caller can't modify it
u := *dei.user
return &u, nil
}
func (*DockerEnvInfoer) Environ() []string {
// Return a clone of the environment so that the caller can't modify it
return os.Environ()
}
func (*DockerEnvInfoer) UserHomeDir() (string, error) {
// We default the working directory of the command to the user's home
// directory. Since this came from inside the container, we cannot guarantee
// that this exists on the host. Return the "real" home directory of the user
// instead.
return os.UserHomeDir()
}
func (dei *DockerEnvInfoer) UserShell(string) (string, error) {
func (dei *DockerEnvInfoer) Shell(string) (string, error) {
return dei.userShell, nil
}
@@ -174,37 +152,49 @@ func (dei *DockerEnvInfoer) ModifyCommand(cmd string, args ...string) (string, [
// devcontainerEnv is a helper function that inspects the container labels to
// find the required environment variables for running a command in the container.
func devcontainerEnv(ctx context.Context, execer agentexec.Execer, container string) ([]string, error) {
ins, stderr, err := runDockerInspect(ctx, execer, container)
stdout, stderr, err := runDockerInspect(ctx, execer, container)
if err != nil {
return nil, xerrors.Errorf("inspect container: %w: %q", err, stderr)
}
ins, _, err := convertDockerInspect(stdout)
if err != nil {
return nil, xerrors.Errorf("inspect container: %w", err)
}
if len(ins) != 1 {
return nil, xerrors.Errorf("inspect container: expected 1 container, got %d", len(ins))
}
in := ins[0]
if in.Config.Labels == nil {
if in.Labels == nil {
return nil, nil
}
// We want to look for the devcontainer metadata, which is in the
// value of the label `devcontainer.metadata`.
rawMeta, ok := in.Config.Labels["devcontainer.metadata"]
rawMeta, ok := in.Labels["devcontainer.metadata"]
if !ok {
return nil, nil
}
meta := struct {
RemoteEnv map[string]string `json:"remoteEnv"`
}{}
meta := make([]dcspec.DevContainer, 0)
if err := json.Unmarshal([]byte(rawMeta), &meta); err != nil {
return nil, xerrors.Errorf("unmarshal devcontainer.metadata: %w", err)
}
// The environment variables are stored in the `remoteEnv` key.
env := make([]string, 0, len(meta.RemoteEnv))
for k, v := range meta.RemoteEnv {
env = append(env, fmt.Sprintf("%s=%s", k, v))
env := make([]string, 0)
for _, m := range meta {
for k, v := range m.RemoteEnv {
if v == nil { // *string per spec
// devcontainer-cli will set this to the string "null" if the value is
// not set. Explicitly setting to an empty string here as this would be
// more expected here.
v = ptr.Ref("")
}
env = append(env, fmt.Sprintf("%s=%s", k, *v))
}
}
slices.Sort(env)
return env, nil
@@ -238,6 +228,19 @@ func run(ctx context.Context, execer agentexec.Execer, cmd string, args ...strin
return stdout, stderr, err
}
// DockerCLILister is a ContainerLister that lists containers using the docker CLI
type DockerCLILister struct {
execer agentexec.Execer
}
var _ Lister = &DockerCLILister{}
func NewDocker(execer agentexec.Execer) Lister {
return &DockerCLILister{
execer: agentexec.DefaultExecer,
}
}
func (dcl *DockerCLILister) List(ctx context.Context) (codersdk.WorkspaceAgentListContainersResponse, error) {
var stdoutBuf, stderrBuf bytes.Buffer
// List all container IDs, one per line, with no truncation
@@ -265,11 +268,16 @@ func (dcl *DockerCLILister) List(ctx context.Context) (codersdk.WorkspaceAgentLi
return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("scan docker ps output: %w", err)
}
res := codersdk.WorkspaceAgentListContainersResponse{
Containers: make([]codersdk.WorkspaceAgentContainer, 0, len(ids)),
Warnings: make([]string, 0),
}
dockerPsStderr := strings.TrimSpace(stderrBuf.String())
if dockerPsStderr != "" {
res.Warnings = append(res.Warnings, dockerPsStderr)
}
if len(ids) == 0 {
return codersdk.WorkspaceAgentListContainersResponse{
Warnings: []string{dockerPsStderr},
}, nil
return res, nil
}
// now we can get the detailed information for each container
@@ -280,26 +288,21 @@ func (dcl *DockerCLILister) List(ctx context.Context) (codersdk.WorkspaceAgentLi
// will still contain valid JSON. We will just end up missing
// information about the removed container. We could potentially
// log this error, but I'm not sure it's worth it.
ins, dockerInspectStderr, err := runDockerInspect(ctx, dcl.execer, ids...)
dockerInspectStdout, dockerInspectStderr, err := runDockerInspect(ctx, dcl.execer, ids...)
if err != nil {
return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("run docker inspect: %w", err)
return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("run docker inspect: %w: %s", err, dockerInspectStderr)
}
res := codersdk.WorkspaceAgentListContainersResponse{
Containers: make([]codersdk.WorkspaceAgentDevcontainer, len(ins)),
}
for idx, in := range ins {
out, warns := convertDockerInspect(in)
res.Warnings = append(res.Warnings, warns...)
res.Containers[idx] = out
if len(dockerInspectStderr) > 0 {
res.Warnings = append(res.Warnings, string(dockerInspectStderr))
}
if dockerPsStderr != "" {
res.Warnings = append(res.Warnings, dockerPsStderr)
}
if dockerInspectStderr != "" {
res.Warnings = append(res.Warnings, dockerInspectStderr)
outs, warns, err := convertDockerInspect(dockerInspectStdout)
if err != nil {
return codersdk.WorkspaceAgentListContainersResponse{}, xerrors.Errorf("convert docker inspect output: %w", err)
}
res.Warnings = append(res.Warnings, warns...)
res.Containers = append(res.Containers, outs...)
return res, nil
}
@@ -307,35 +310,34 @@ func (dcl *DockerCLILister) List(ctx context.Context) (codersdk.WorkspaceAgentLi
// runDockerInspect is a helper function that runs `docker inspect` on the given
// container IDs and returns the parsed output.
// The stderr output is also returned for logging purposes.
func runDockerInspect(ctx context.Context, execer agentexec.Execer, ids ...string) ([]dockerInspect, string, error) {
func runDockerInspect(ctx context.Context, execer agentexec.Execer, ids ...string) (stdout, stderr []byte, err error) {
var stdoutBuf, stderrBuf bytes.Buffer
cmd := execer.CommandContext(ctx, "docker", append([]string{"inspect"}, ids...)...)
cmd.Stdout = &stdoutBuf
cmd.Stderr = &stderrBuf
err := cmd.Run()
stderr := strings.TrimSpace(stderrBuf.String())
err = cmd.Run()
stdout = bytes.TrimSpace(stdoutBuf.Bytes())
stderr = bytes.TrimSpace(stderrBuf.Bytes())
if err != nil {
return nil, stderr, err
if bytes.Contains(stderr, []byte("No such object:")) {
// This can happen if a container is deleted between the time we check for its existence and the time we inspect it.
return stdout, stderr, nil
}
return stdout, stderr, err
}
var ins []dockerInspect
if err := json.NewDecoder(&stdoutBuf).Decode(&ins); err != nil {
return nil, stderr, xerrors.Errorf("decode docker inspect output: %w", err)
}
return ins, stderr, nil
return stdout, stderr, nil
}
// To avoid a direct dependency on the Docker API, we use the docker CLI
// to fetch information about containers.
type dockerInspect struct {
ID string `json:"Id"`
Created time.Time `json:"Created"`
Config dockerInspectConfig `json:"Config"`
HostConfig dockerInspectHostConfig `json:"HostConfig"`
Name string `json:"Name"`
Mounts []dockerInspectMount `json:"Mounts"`
State dockerInspectState `json:"State"`
ID string `json:"Id"`
Created time.Time `json:"Created"`
Config dockerInspectConfig `json:"Config"`
Name string `json:"Name"`
Mounts []dockerInspectMount `json:"Mounts"`
State dockerInspectState `json:"State"`
NetworkSettings dockerInspectNetworkSettings `json:"NetworkSettings"`
}
type dockerInspectConfig struct {
@@ -343,8 +345,9 @@ type dockerInspectConfig struct {
Labels map[string]string `json:"Labels"`
}
type dockerInspectHostConfig struct {
PortBindings map[string]any `json:"PortBindings"`
type dockerInspectPort struct {
HostIP string `json:"HostIp"`
HostPort string `json:"HostPort"`
}
type dockerInspectMount struct {
@@ -359,6 +362,10 @@ type dockerInspectState struct {
Error string `json:"Error"`
}
type dockerInspectNetworkSettings struct {
Ports map[string][]dockerInspectPort `json:"Ports"`
}
func (dis dockerInspectState) String() string {
if dis.Running {
return "running"
@@ -376,50 +383,109 @@ func (dis dockerInspectState) String() string {
return sb.String()
}
func convertDockerInspect(in dockerInspect) (codersdk.WorkspaceAgentDevcontainer, []string) {
func convertDockerInspect(raw []byte) ([]codersdk.WorkspaceAgentContainer, []string, error) {
var warns []string
out := codersdk.WorkspaceAgentDevcontainer{
CreatedAt: in.Created,
// Remove the leading slash from the container name
FriendlyName: strings.TrimPrefix(in.Name, "/"),
ID: in.ID,
Image: in.Config.Image,
Labels: in.Config.Labels,
Ports: make([]codersdk.WorkspaceAgentListeningPort, 0),
Running: in.State.Running,
Status: in.State.String(),
Volumes: make(map[string]string, len(in.Mounts)),
var ins []dockerInspect
if err := json.NewDecoder(bytes.NewReader(raw)).Decode(&ins); err != nil {
return nil, nil, xerrors.Errorf("decode docker inspect output: %w", err)
}
outs := make([]codersdk.WorkspaceAgentContainer, 0, len(ins))
// Say you have two containers:
// - Container A with Host IP 127.0.0.1:8000 mapped to container port 8001
// - Container B with Host IP [::1]:8000 mapped to container port 8001
// A request to localhost:8000 may be routed to either container.
// We don't know which one for sure, so we need to surface this to the user.
// Keep track of all host ports we see. If we see the same host port
// mapped to multiple containers on different host IPs, we need to
// warn the user about this.
// Note that we only do this for loopback or unspecified IPs.
// We'll assume that the user knows what they're doing if they bind to
// a specific IP address.
hostPortContainers := make(map[int][]string)
for _, in := range ins {
out := codersdk.WorkspaceAgentContainer{
CreatedAt: in.Created,
// Remove the leading slash from the container name
FriendlyName: strings.TrimPrefix(in.Name, "/"),
ID: in.ID,
Image: in.Config.Image,
Labels: in.Config.Labels,
Ports: make([]codersdk.WorkspaceAgentContainerPort, 0),
Running: in.State.Running,
Status: in.State.String(),
Volumes: make(map[string]string, len(in.Mounts)),
}
if in.NetworkSettings.Ports == nil {
in.NetworkSettings.Ports = make(map[string][]dockerInspectPort)
}
portKeys := maps.Keys(in.NetworkSettings.Ports)
// Sort the ports for deterministic output.
sort.Strings(portKeys)
// If we see the same port bound to both ipv4 and ipv6 loopback or unspecified
// interfaces to the same container port, there is no point in adding it multiple times.
loopbackHostPortContainerPorts := make(map[int]uint16, 0)
for _, pk := range portKeys {
for _, p := range in.NetworkSettings.Ports[pk] {
cp, network, err := convertDockerPort(pk)
if err != nil {
warns = append(warns, fmt.Sprintf("convert docker port: %s", err.Error()))
// Default network to "tcp" if we can't parse it.
network = "tcp"
}
hp, err := strconv.Atoi(p.HostPort)
if err != nil {
warns = append(warns, fmt.Sprintf("convert docker host port: %s", err.Error()))
continue
}
if hp > 65535 || hp < 1 { // invalid port
warns = append(warns, fmt.Sprintf("convert docker host port: invalid host port %d", hp))
continue
}
// Deduplicate host ports for loopback and unspecified IPs.
if isLoopbackOrUnspecified(p.HostIP) {
if found, ok := loopbackHostPortContainerPorts[hp]; ok && found == cp {
// We've already seen this port, so skip it.
continue
}
loopbackHostPortContainerPorts[hp] = cp
// Also keep track of the host port and the container ID.
hostPortContainers[hp] = append(hostPortContainers[hp], in.ID)
}
out.Ports = append(out.Ports, codersdk.WorkspaceAgentContainerPort{
Network: network,
Port: cp,
// #nosec G115 - Safe conversion since Docker ports are limited to uint16 range
HostPort: uint16(hp),
HostIP: p.HostIP,
})
}
}
if in.Mounts == nil {
in.Mounts = []dockerInspectMount{}
}
// Sort the mounts for deterministic output.
sort.Slice(in.Mounts, func(i, j int) bool {
return in.Mounts[i].Source < in.Mounts[j].Source
})
for _, k := range in.Mounts {
out.Volumes[k.Source] = k.Destination
}
outs = append(outs, out)
}
if in.HostConfig.PortBindings == nil {
in.HostConfig.PortBindings = make(map[string]any)
}
portKeys := maps.Keys(in.HostConfig.PortBindings)
// Sort the ports for deterministic output.
sort.Strings(portKeys)
for _, p := range portKeys {
if port, network, err := convertDockerPort(p); err != nil {
warns = append(warns, err.Error())
} else {
out.Ports = append(out.Ports, codersdk.WorkspaceAgentListeningPort{
Network: network,
Port: port,
})
// Check if any host ports are mapped to multiple containers.
for hp, ids := range hostPortContainers {
if len(ids) > 1 {
warns = append(warns, fmt.Sprintf("host port %d is mapped to multiple containers on different interfaces: %s", hp, strings.Join(ids, ", ")))
}
}
if in.Mounts == nil {
in.Mounts = []dockerInspectMount{}
}
// Sort the mounts for deterministic output.
sort.Slice(in.Mounts, func(i, j int) bool {
return in.Mounts[i].Source < in.Mounts[j].Source
})
for _, k := range in.Mounts {
out.Volumes[k.Source] = k.Destination
}
return out, warns
return outs, warns, nil
}
// convertDockerPort converts a Docker port string to a port number and network
@@ -428,21 +494,26 @@ func convertDockerInspect(in dockerInspect) (codersdk.WorkspaceAgentDevcontainer
// "8080" -> 8080, "tcp"
func convertDockerPort(in string) (uint16, string, error) {
parts := strings.Split(in, "/")
p, err := strconv.ParseUint(parts[0], 10, 16)
if err != nil {
return 0, "", xerrors.Errorf("invalid port format: %s", in)
}
switch len(parts) {
case 1:
// assume it's a TCP port
p, err := strconv.Atoi(parts[0])
if err != nil {
return 0, "", xerrors.Errorf("invalid port format: %s", in)
}
return uint16(p), "tcp", nil
case 2:
p, err := strconv.Atoi(parts[0])
if err != nil {
return 0, "", xerrors.Errorf("invalid port format: %s", in)
}
return uint16(p), parts[1], nil
default:
return 0, "", xerrors.Errorf("invalid port format: %s", in)
}
}
// convenience function to check if an IP address is loopback or unspecified
func isLoopbackOrUnspecified(ips string) bool {
nip := net.ParseIP(ips)
if nip == nil {
return false // technically correct, I suppose
}
return nip.IsLoopback() || nip.IsUnspecified()
}
+242 -388
View File
@@ -1,159 +1,18 @@
package agentcontainers
import (
"fmt"
"os"
"slices"
"strconv"
"strings"
"path/filepath"
"testing"
"time"
"go.uber.org/mock/gomock"
"github.com/google/uuid"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/agent/agentcontainers/acmock"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/pty"
"github.com/coder/coder/v2/testutil"
"github.com/coder/quartz"
)
// TestIntegrationDocker tests agentcontainers functionality using a real
// Docker container. It starts a container with a known
// label, lists the containers, and verifies that the expected container is
// returned. It also executes a sample command inside the container.
// The container is deleted after the test is complete.
// As this test creates containers, it is skipped by default.
// It can be run manually as follows:
//
// CODER_TEST_USE_DOCKER=1 go test ./agent/agentcontainers -run TestDockerCLIContainerLister
func TestIntegrationDocker(t *testing.T) {
t.Parallel()
if ctud, ok := os.LookupEnv("CODER_TEST_USE_DOCKER"); !ok || ctud != "1" {
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
}
pool, err := dockertest.NewPool("")
require.NoError(t, err, "Could not connect to docker")
testLabelValue := uuid.New().String()
// Create a temporary directory to validate that we surface mounts correctly.
testTempDir := t.TempDir()
// Pick a random port to expose for testing port bindings.
testRandPort := testutil.RandomPortNoListen(t)
ct, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: "busybox",
Tag: "latest",
Cmd: []string{"sleep", "infnity"},
Labels: map[string]string{
"com.coder.test": testLabelValue,
"devcontainer.metadata": `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`,
},
Mounts: []string{testTempDir + ":" + testTempDir},
ExposedPorts: []string{fmt.Sprintf("%d/tcp", testRandPort)},
PortBindings: map[docker.Port][]docker.PortBinding{
docker.Port(fmt.Sprintf("%d/tcp", testRandPort)): {
{
HostIP: "0.0.0.0",
HostPort: strconv.FormatInt(int64(testRandPort), 10),
},
},
},
}, func(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
})
require.NoError(t, err, "Could not start test docker container")
t.Logf("Created container %q", ct.Container.Name)
t.Cleanup(func() {
assert.NoError(t, pool.Purge(ct), "Could not purge resource %q", ct.Container.Name)
t.Logf("Purged container %q", ct.Container.Name)
})
// Wait for container to start
require.Eventually(t, func() bool {
ct, ok := pool.ContainerByName(ct.Container.Name)
return ok && ct.Container.State.Running
}, testutil.WaitShort, testutil.IntervalSlow, "Container did not start in time")
dcl := NewDocker(agentexec.DefaultExecer)
ctx := testutil.Context(t, testutil.WaitShort)
actual, err := dcl.List(ctx)
require.NoError(t, err, "Could not list containers")
require.Empty(t, actual.Warnings, "Expected no warnings")
var found bool
for _, foundContainer := range actual.Containers {
if foundContainer.ID == ct.Container.ID {
found = true
assert.Equal(t, ct.Container.Created, foundContainer.CreatedAt)
// ory/dockertest pre-pends a forward slash to the container name.
assert.Equal(t, strings.TrimPrefix(ct.Container.Name, "/"), foundContainer.FriendlyName)
// ory/dockertest returns the sha256 digest of the image.
assert.Equal(t, "busybox:latest", foundContainer.Image)
assert.Equal(t, ct.Container.Config.Labels, foundContainer.Labels)
assert.True(t, foundContainer.Running)
assert.Equal(t, "running", foundContainer.Status)
if assert.Len(t, foundContainer.Ports, 1) {
assert.Equal(t, testRandPort, foundContainer.Ports[0].Port)
assert.Equal(t, "tcp", foundContainer.Ports[0].Network)
}
if assert.Len(t, foundContainer.Volumes, 1) {
assert.Equal(t, testTempDir, foundContainer.Volumes[testTempDir])
}
// Test that EnvInfo is able to correctly modify a command to be
// executed inside the container.
dei, err := EnvInfo(ctx, agentexec.DefaultExecer, ct.Container.ID, "")
require.NoError(t, err, "Expected no error from DockerEnvInfo()")
ptyWrappedCmd, ptyWrappedArgs := dei.ModifyCommand("/bin/sh", "--norc")
ptyCmd, ptyPs, err := pty.Start(agentexec.DefaultExecer.PTYCommandContext(ctx, ptyWrappedCmd, ptyWrappedArgs...))
require.NoError(t, err, "failed to start pty command")
t.Cleanup(func() {
_ = ptyPs.Kill()
_ = ptyCmd.Close()
})
tr := testutil.NewTerminalReader(t, ptyCmd.OutputReader())
matchPrompt := func(line string) bool {
return strings.Contains(line, "#")
}
matchHostnameCmd := func(line string) bool {
return strings.Contains(strings.TrimSpace(line), "hostname")
}
matchHostnameOuput := func(line string) bool {
return strings.Contains(strings.TrimSpace(line), ct.Container.Config.Hostname)
}
matchEnvCmd := func(line string) bool {
return strings.Contains(strings.TrimSpace(line), "env")
}
matchEnvOutput := func(line string) bool {
return strings.Contains(line, "FOO=bar") || strings.Contains(line, "MULTILINE=foo")
}
require.NoError(t, tr.ReadUntil(ctx, matchPrompt), "failed to match prompt")
t.Logf("Matched prompt")
_, err = ptyCmd.InputWriter().Write([]byte("hostname\r\n"))
require.NoError(t, err, "failed to write to pty")
t.Logf("Wrote hostname command")
require.NoError(t, tr.ReadUntil(ctx, matchHostnameCmd), "failed to match hostname command")
t.Logf("Matched hostname command")
require.NoError(t, tr.ReadUntil(ctx, matchHostnameOuput), "failed to match hostname output")
t.Logf("Matched hostname output")
_, err = ptyCmd.InputWriter().Write([]byte("env\r\n"))
require.NoError(t, err, "failed to write to pty")
t.Logf("Wrote env command")
require.NoError(t, tr.ReadUntil(ctx, matchEnvCmd), "failed to match env command")
t.Logf("Matched env command")
require.NoError(t, tr.ReadUntil(ctx, matchEnvOutput), "failed to match env output")
t.Logf("Matched env output")
break
}
}
assert.True(t, found, "Expected to find container with label 'com.coder.test=%s'", testLabelValue)
}
func TestWrapDockerExec(t *testing.T) {
t.Parallel()
tests := []struct {
@@ -192,123 +51,10 @@ func TestWrapDockerExec(t *testing.T) {
}
}
// TestContainersHandler tests the containersHandler.getContainers method using
// a mock implementation. It specifically tests caching behavior.
func TestContainersHandler(t *testing.T) {
t.Parallel()
t.Run("list", func(t *testing.T) {
t.Parallel()
fakeCt := fakeContainer(t)
fakeCt2 := fakeContainer(t)
makeResponse := func(cts ...codersdk.WorkspaceAgentDevcontainer) codersdk.WorkspaceAgentListContainersResponse {
return codersdk.WorkspaceAgentListContainersResponse{Containers: cts}
}
// Each test case is called multiple times to ensure idempotency
for _, tc := range []struct {
name string
// data to be stored in the handler
cacheData codersdk.WorkspaceAgentListContainersResponse
// duration of cache
cacheDur time.Duration
// relative age of the cached data
cacheAge time.Duration
// function to set up expectations for the mock
setupMock func(*acmock.MockLister)
// expected result
expected codersdk.WorkspaceAgentListContainersResponse
// expected error
expectedErr string
}{
{
name: "no cache",
setupMock: func(mcl *acmock.MockLister) {
mcl.EXPECT().List(gomock.Any()).Return(makeResponse(fakeCt), nil).AnyTimes()
},
expected: makeResponse(fakeCt),
},
{
name: "no data",
cacheData: makeResponse(),
cacheAge: 2 * time.Second,
cacheDur: time.Second,
setupMock: func(mcl *acmock.MockLister) {
mcl.EXPECT().List(gomock.Any()).Return(makeResponse(fakeCt), nil).AnyTimes()
},
expected: makeResponse(fakeCt),
},
{
name: "cached data",
cacheAge: time.Second,
cacheData: makeResponse(fakeCt),
cacheDur: 2 * time.Second,
expected: makeResponse(fakeCt),
},
{
name: "lister error",
setupMock: func(mcl *acmock.MockLister) {
mcl.EXPECT().List(gomock.Any()).Return(makeResponse(), assert.AnError).AnyTimes()
},
expectedErr: assert.AnError.Error(),
},
{
name: "stale cache",
cacheAge: 2 * time.Second,
cacheData: makeResponse(fakeCt),
cacheDur: time.Second,
setupMock: func(mcl *acmock.MockLister) {
mcl.EXPECT().List(gomock.Any()).Return(makeResponse(fakeCt2), nil).AnyTimes()
},
expected: makeResponse(fakeCt2),
},
} {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var (
ctx = testutil.Context(t, testutil.WaitShort)
clk = quartz.NewMock(t)
ctrl = gomock.NewController(t)
mockLister = acmock.NewMockLister(ctrl)
now = time.Now().UTC()
ch = devcontainersHandler{
cacheDuration: tc.cacheDur,
cl: mockLister,
clock: clk,
containers: &tc.cacheData,
lockCh: make(chan struct{}, 1),
}
)
if tc.cacheAge != 0 {
ch.mtime = now.Add(-tc.cacheAge)
}
if tc.setupMock != nil {
tc.setupMock(mockLister)
}
clk.Set(now).MustWait(ctx)
// Repeat the test to ensure idempotency
for i := 0; i < 2; i++ {
actual, err := ch.getContainers(ctx)
if tc.expectedErr != "" {
require.Empty(t, actual, "expected no data (attempt %d)", i)
require.ErrorContains(t, err, tc.expectedErr, "expected error (attempt %d)", i)
} else {
require.NoError(t, err, "expected no error (attempt %d)", i)
require.Equal(t, tc.expected, actual, "expected containers to be equal (attempt %d)", i)
}
}
})
}
})
}
func TestConvertDockerPort(t *testing.T) {
t.Parallel()
//nolint:paralleltest // variable recapture no longer required
for _, tc := range []struct {
name string
in string
@@ -355,7 +101,7 @@ func TestConvertDockerPort(t *testing.T) {
expectError: "invalid port",
},
} {
tc := tc // not needed anymore but makes the linter happy
//nolint: paralleltest // variable recapture no longer required
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
actualPort, actualNetwork, actualErr := convertDockerPort(tc.in)
@@ -412,153 +158,261 @@ func TestConvertDockerVolume(t *testing.T) {
}
}
// TestDockerEnvInfoer tests the ability of EnvInfo to extract information from
// running containers. Containers are deleted after the test is complete.
// As this test creates containers, it is skipped by default.
// It can be run manually as follows:
//
// CODER_TEST_USE_DOCKER=1 go test ./agent/agentcontainers -run TestDockerEnvInfoer
func TestDockerEnvInfoer(t *testing.T) {
// TestConvertDockerInspect tests the convertDockerInspect function using
// fixtures from ./testdata.
func TestConvertDockerInspect(t *testing.T) {
t.Parallel()
if ctud, ok := os.LookupEnv("CODER_TEST_USE_DOCKER"); !ok || ctud != "1" {
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
}
pool, err := dockertest.NewPool("")
require.NoError(t, err, "Could not connect to docker")
// nolint:paralleltest // variable recapture no longer required
for idx, tt := range []struct {
image string
labels map[string]string
expectedEnv []string
containerUser string
expectedUsername string
expectedUserShell string
//nolint:paralleltest // variable recapture no longer required
for _, tt := range []struct {
name string
expect []codersdk.WorkspaceAgentContainer
expectWarns []string
expectError string
}{
{
image: "busybox:latest",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
expectedUsername: "root",
expectedUserShell: "/bin/sh",
name: "container_simple",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 55, 58, 91280203, time.UTC),
ID: "6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286",
FriendlyName: "eloquent_kowalevski",
Image: "debian:bookworm",
Labels: map[string]string{},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{},
Volumes: map[string]string{},
},
},
},
{
image: "busybox:latest",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
expectedUserShell: "/bin/sh",
name: "container_labels",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 20, 3, 28, 71706536, time.UTC),
ID: "bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f",
FriendlyName: "fervent_bardeen",
Image: "debian:bookworm",
Labels: map[string]string{"baz": "zap", "foo": "bar"},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{},
Volumes: map[string]string{},
},
},
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
expectedUsername: "coder",
expectedUserShell: "/bin/bash",
name: "container_binds",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 58, 43, 522505027, time.UTC),
ID: "fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a",
FriendlyName: "silly_beaver",
Image: "debian:bookworm",
Labels: map[string]string{},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{},
Volumes: map[string]string{
"/tmp/test/a": "/var/coder/a",
"/tmp/test/b": "/var/coder/b",
},
},
},
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "coder",
expectedUsername: "coder",
expectedUserShell: "/bin/bash",
name: "container_sameport",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 56, 34, 842164541, time.UTC),
ID: "4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2",
FriendlyName: "modest_varahamihira",
Image: "debian:bookworm",
Labels: map[string]string{},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{
{
Network: "tcp",
Port: 12345,
HostPort: 12345,
HostIP: "0.0.0.0",
},
},
Volumes: map[string]string{},
},
},
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
expectedUserShell: "/bin/bash",
name: "container_differentport",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 57, 8, 862545133, time.UTC),
ID: "3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea",
FriendlyName: "boring_ellis",
Image: "debian:bookworm",
Labels: map[string]string{},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{
{
Network: "tcp",
Port: 23456,
HostPort: 12345,
HostIP: "0.0.0.0",
},
},
Volumes: map[string]string{},
},
},
},
{
name: "container_sameportdiffip",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 56, 34, 842164541, time.UTC),
ID: "a",
FriendlyName: "a",
Image: "debian:bookworm",
Labels: map[string]string{},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{
{
Network: "tcp",
Port: 8001,
HostPort: 8000,
HostIP: "0.0.0.0",
},
},
Volumes: map[string]string{},
},
{
CreatedAt: time.Date(2025, 3, 11, 17, 56, 34, 842164541, time.UTC),
ID: "b",
FriendlyName: "b",
Image: "debian:bookworm",
Labels: map[string]string{},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{
{
Network: "tcp",
Port: 8001,
HostPort: 8000,
HostIP: "::",
},
},
Volumes: map[string]string{},
},
},
expectWarns: []string{"host port 8000 is mapped to multiple containers on different interfaces: a, b"},
},
{
name: "container_volume",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 59, 42, 39484134, time.UTC),
ID: "b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e",
FriendlyName: "upbeat_carver",
Image: "debian:bookworm",
Labels: map[string]string{},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{},
Volumes: map[string]string{
"/var/lib/docker/volumes/testvol/_data": "/testvol",
},
},
},
},
{
name: "devcontainer_simple",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 1, 5, 751972661, time.UTC),
ID: "0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed",
FriendlyName: "optimistic_hopper",
Image: "debian:bookworm",
Labels: map[string]string{
"devcontainer.config_file": "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_simple.json",
"devcontainer.metadata": "[]",
},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{},
Volumes: map[string]string{},
},
},
},
{
name: "devcontainer_forwardport",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 3, 55, 22053072, time.UTC),
ID: "4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067",
FriendlyName: "serene_khayyam",
Image: "debian:bookworm",
Labels: map[string]string{
"devcontainer.config_file": "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_forwardport.json",
"devcontainer.metadata": "[]",
},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{},
Volumes: map[string]string{},
},
},
},
{
name: "devcontainer_appport",
expect: []codersdk.WorkspaceAgentContainer{
{
CreatedAt: time.Date(2025, 3, 11, 17, 2, 42, 613747761, time.UTC),
ID: "52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3",
FriendlyName: "suspicious_margulis",
Image: "debian:bookworm",
Labels: map[string]string{
"devcontainer.config_file": "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_appport.json",
"devcontainer.metadata": "[]",
},
Running: true,
Status: "running",
Ports: []codersdk.WorkspaceAgentContainerPort{
{
Network: "tcp",
Port: 8080,
HostPort: 32768,
HostIP: "0.0.0.0",
},
},
Volumes: map[string]string{},
},
},
},
} {
t.Run(fmt.Sprintf("#%d", idx), func(t *testing.T) {
// nolint:paralleltest // variable recapture no longer required
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
// Start a container with the given image
// and environment variables
image := strings.Split(tt.image, ":")[0]
tag := strings.Split(tt.image, ":")[1]
ct, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: image,
Tag: tag,
Cmd: []string{"sleep", "infinity"},
Labels: tt.labels,
}, func(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
})
require.NoError(t, err, "Could not start test docker container")
t.Logf("Created container %q", ct.Container.Name)
t.Cleanup(func() {
assert.NoError(t, pool.Purge(ct), "Could not purge resource %q", ct.Container.Name)
t.Logf("Purged container %q", ct.Container.Name)
})
ctx := testutil.Context(t, testutil.WaitShort)
dei, err := EnvInfo(ctx, agentexec.DefaultExecer, ct.Container.ID, tt.containerUser)
require.NoError(t, err, "Expected no error from DockerEnvInfo()")
u, err := dei.CurrentUser()
require.NoError(t, err, "Expected no error from CurrentUser()")
require.Equal(t, tt.expectedUsername, u.Username, "Expected username to match")
hd, err := dei.UserHomeDir()
require.NoError(t, err, "Expected no error from UserHomeDir()")
require.NotEmpty(t, hd, "Expected user homedir to be non-empty")
sh, err := dei.UserShell(tt.containerUser)
require.NoError(t, err, "Expected no error from UserShell()")
require.Equal(t, tt.expectedUserShell, sh, "Expected user shell to match")
// We don't need to test the actual environment variables here.
environ := dei.Environ()
require.NotEmpty(t, environ, "Expected environ to be non-empty")
// Test that the environment variables are present in modified command
// output.
envCmd, envArgs := dei.ModifyCommand("env")
for _, env := range tt.expectedEnv {
require.Subset(t, envArgs, []string{"--env", env})
bs, err := os.ReadFile(filepath.Join("testdata", tt.name, "docker_inspect.json"))
require.NoError(t, err, "failed to read testdata file")
actual, warns, err := convertDockerInspect(bs)
if len(tt.expectWarns) > 0 {
assert.Len(t, warns, len(tt.expectWarns), "expected warnings")
for _, warn := range tt.expectWarns {
assert.Contains(t, warns, warn)
}
}
// Run the command in the container and check the output
// HACK: we remove the --tty argument because we're not running in a tty
envArgs = slices.DeleteFunc(envArgs, func(s string) bool { return s == "--tty" })
stdout, stderr, err := run(ctx, agentexec.DefaultExecer, envCmd, envArgs...)
require.Empty(t, stderr, "Expected no stderr output")
require.NoError(t, err, "Expected no error from running command")
for _, env := range tt.expectedEnv {
require.Contains(t, stdout, env)
if tt.expectError != "" {
assert.Empty(t, actual, "expected no data")
assert.ErrorContains(t, err, tt.expectError)
return
}
require.NoError(t, err, "expected no error")
if diff := cmp.Diff(tt.expect, actual); diff != "" {
t.Errorf("unexpected diff (-want +got):\n%s", diff)
}
})
}
}
func fakeContainer(t *testing.T, mut ...func(*codersdk.WorkspaceAgentDevcontainer)) codersdk.WorkspaceAgentDevcontainer {
t.Helper()
ct := codersdk.WorkspaceAgentDevcontainer{
CreatedAt: time.Now().UTC(),
ID: uuid.New().String(),
FriendlyName: testutil.GetRandomName(t),
Image: testutil.GetRandomName(t) + ":" + strings.Split(uuid.New().String(), "-")[0],
Labels: map[string]string{
testutil.GetRandomName(t): testutil.GetRandomName(t),
},
Running: true,
Ports: []codersdk.WorkspaceAgentListeningPort{
{
Network: "tcp",
Port: testutil.RandomPortNoListen(t),
},
},
Status: testutil.MustRandString(t, 10),
Volumes: map[string]string{testutil.GetRandomName(t): testutil.GetRandomName(t)},
}
for _, m := range mut {
m(&ct)
}
return ct
}
+296
View File
@@ -0,0 +1,296 @@
package agentcontainers_test
import (
"context"
"fmt"
"os"
"slices"
"strconv"
"strings"
"testing"
"github.com/google/uuid"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/agent/agentcontainers"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/pty"
"github.com/coder/coder/v2/testutil"
)
// TestIntegrationDocker tests agentcontainers functionality using a real
// Docker container. It starts a container with a known
// label, lists the containers, and verifies that the expected container is
// returned. It also executes a sample command inside the container.
// The container is deleted after the test is complete.
// As this test creates containers, it is skipped by default.
// It can be run manually as follows:
//
// CODER_TEST_USE_DOCKER=1 go test ./agent/agentcontainers -run TestDockerCLIContainerLister
//
//nolint:paralleltest // This test tends to flake when lots of containers start and stop in parallel.
func TestIntegrationDocker(t *testing.T) {
if ctud, ok := os.LookupEnv("CODER_TEST_USE_DOCKER"); !ok || ctud != "1" {
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
}
pool, err := dockertest.NewPool("")
require.NoError(t, err, "Could not connect to docker")
testLabelValue := uuid.New().String()
// Create a temporary directory to validate that we surface mounts correctly.
testTempDir := t.TempDir()
// Pick a random port to expose for testing port bindings.
testRandPort := testutil.RandomPortNoListen(t)
ct, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: "busybox",
Tag: "latest",
Cmd: []string{"sleep", "infnity"},
Labels: map[string]string{
"com.coder.test": testLabelValue,
"devcontainer.metadata": `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`,
},
Mounts: []string{testTempDir + ":" + testTempDir},
ExposedPorts: []string{fmt.Sprintf("%d/tcp", testRandPort)},
PortBindings: map[docker.Port][]docker.PortBinding{
docker.Port(fmt.Sprintf("%d/tcp", testRandPort)): {
{
HostIP: "0.0.0.0",
HostPort: strconv.FormatInt(int64(testRandPort), 10),
},
},
},
}, func(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
})
require.NoError(t, err, "Could not start test docker container")
t.Logf("Created container %q", ct.Container.Name)
t.Cleanup(func() {
assert.NoError(t, pool.Purge(ct), "Could not purge resource %q", ct.Container.Name)
t.Logf("Purged container %q", ct.Container.Name)
})
// Wait for container to start
require.Eventually(t, func() bool {
ct, ok := pool.ContainerByName(ct.Container.Name)
return ok && ct.Container.State.Running
}, testutil.WaitShort, testutil.IntervalSlow, "Container did not start in time")
dcl := agentcontainers.NewDocker(agentexec.DefaultExecer)
ctx := testutil.Context(t, testutil.WaitShort)
actual, err := dcl.List(ctx)
require.NoError(t, err, "Could not list containers")
require.Empty(t, actual.Warnings, "Expected no warnings")
var found bool
for _, foundContainer := range actual.Containers {
if foundContainer.ID == ct.Container.ID {
found = true
assert.Equal(t, ct.Container.Created, foundContainer.CreatedAt)
// ory/dockertest pre-pends a forward slash to the container name.
assert.Equal(t, strings.TrimPrefix(ct.Container.Name, "/"), foundContainer.FriendlyName)
// ory/dockertest returns the sha256 digest of the image.
assert.Equal(t, "busybox:latest", foundContainer.Image)
assert.Equal(t, ct.Container.Config.Labels, foundContainer.Labels)
assert.True(t, foundContainer.Running)
assert.Equal(t, "running", foundContainer.Status)
if assert.Len(t, foundContainer.Ports, 1) {
assert.Equal(t, testRandPort, foundContainer.Ports[0].Port)
assert.Equal(t, "tcp", foundContainer.Ports[0].Network)
}
if assert.Len(t, foundContainer.Volumes, 1) {
assert.Equal(t, testTempDir, foundContainer.Volumes[testTempDir])
}
// Test that EnvInfo is able to correctly modify a command to be
// executed inside the container.
dei, err := agentcontainers.EnvInfo(ctx, agentexec.DefaultExecer, ct.Container.ID, "")
require.NoError(t, err, "Expected no error from DockerEnvInfo()")
ptyWrappedCmd, ptyWrappedArgs := dei.ModifyCommand("/bin/sh", "--norc")
ptyCmd, ptyPs, err := pty.Start(agentexec.DefaultExecer.PTYCommandContext(ctx, ptyWrappedCmd, ptyWrappedArgs...))
require.NoError(t, err, "failed to start pty command")
t.Cleanup(func() {
_ = ptyPs.Kill()
_ = ptyCmd.Close()
})
tr := testutil.NewTerminalReader(t, ptyCmd.OutputReader())
matchPrompt := func(line string) bool {
return strings.Contains(line, "#")
}
matchHostnameCmd := func(line string) bool {
return strings.Contains(strings.TrimSpace(line), "hostname")
}
matchHostnameOuput := func(line string) bool {
return strings.Contains(strings.TrimSpace(line), ct.Container.Config.Hostname)
}
matchEnvCmd := func(line string) bool {
return strings.Contains(strings.TrimSpace(line), "env")
}
matchEnvOutput := func(line string) bool {
return strings.Contains(line, "FOO=bar") || strings.Contains(line, "MULTILINE=foo")
}
require.NoError(t, tr.ReadUntil(ctx, matchPrompt), "failed to match prompt")
t.Logf("Matched prompt")
_, err = ptyCmd.InputWriter().Write([]byte("hostname\r\n"))
require.NoError(t, err, "failed to write to pty")
t.Logf("Wrote hostname command")
require.NoError(t, tr.ReadUntil(ctx, matchHostnameCmd), "failed to match hostname command")
t.Logf("Matched hostname command")
require.NoError(t, tr.ReadUntil(ctx, matchHostnameOuput), "failed to match hostname output")
t.Logf("Matched hostname output")
_, err = ptyCmd.InputWriter().Write([]byte("env\r\n"))
require.NoError(t, err, "failed to write to pty")
t.Logf("Wrote env command")
require.NoError(t, tr.ReadUntil(ctx, matchEnvCmd), "failed to match env command")
t.Logf("Matched env command")
require.NoError(t, tr.ReadUntil(ctx, matchEnvOutput), "failed to match env output")
t.Logf("Matched env output")
break
}
}
assert.True(t, found, "Expected to find container with label 'com.coder.test=%s'", testLabelValue)
}
// TestDockerEnvInfoer tests the ability of EnvInfo to extract information from
// running containers. Containers are deleted after the test is complete.
// As this test creates containers, it is skipped by default.
// It can be run manually as follows:
//
// CODER_TEST_USE_DOCKER=1 go test ./agent/agentcontainers -run TestDockerEnvInfoer
//
//nolint:paralleltest // This test tends to flake when lots of containers start and stop in parallel.
func TestDockerEnvInfoer(t *testing.T) {
if ctud, ok := os.LookupEnv("CODER_TEST_USE_DOCKER"); !ok || ctud != "1" {
t.Skip("Set CODER_TEST_USE_DOCKER=1 to run this test")
}
pool, err := dockertest.NewPool("")
require.NoError(t, err, "Could not connect to docker")
// nolint:paralleltest // variable recapture no longer required
for idx, tt := range []struct {
image string
labels map[string]string
expectedEnv []string
containerUser string
expectedUsername string
expectedUserShell string
}{
{
image: "busybox:latest",
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
expectedUsername: "root",
expectedUserShell: "/bin/sh",
},
{
image: "busybox:latest",
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
expectedUserShell: "/bin/sh",
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
expectedUsername: "coder",
expectedUserShell: "/bin/bash",
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "coder",
expectedUsername: "coder",
expectedUserShell: "/bin/bash",
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar", "MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
expectedUserShell: "/bin/bash",
},
{
image: "codercom/enterprise-minimal:ubuntu",
labels: map[string]string{`devcontainer.metadata`: `[{"remoteEnv": {"FOO": "bar"}},{"remoteEnv": {"MULTILINE": "foo\nbar\nbaz"}}]`},
expectedEnv: []string{"FOO=bar", "MULTILINE=foo\nbar\nbaz"},
containerUser: "root",
expectedUsername: "root",
expectedUserShell: "/bin/bash",
},
} {
//nolint:paralleltest // variable recapture no longer required
t.Run(fmt.Sprintf("#%d", idx), func(t *testing.T) {
// Start a container with the given image
// and environment variables
image := strings.Split(tt.image, ":")[0]
tag := strings.Split(tt.image, ":")[1]
ct, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: image,
Tag: tag,
Cmd: []string{"sleep", "infinity"},
Labels: tt.labels,
}, func(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.RestartPolicy{Name: "no"}
})
require.NoError(t, err, "Could not start test docker container")
t.Logf("Created container %q", ct.Container.Name)
t.Cleanup(func() {
assert.NoError(t, pool.Purge(ct), "Could not purge resource %q", ct.Container.Name)
t.Logf("Purged container %q", ct.Container.Name)
})
ctx := testutil.Context(t, testutil.WaitShort)
dei, err := agentcontainers.EnvInfo(ctx, agentexec.DefaultExecer, ct.Container.ID, tt.containerUser)
require.NoError(t, err, "Expected no error from DockerEnvInfo()")
u, err := dei.User()
require.NoError(t, err, "Expected no error from CurrentUser()")
require.Equal(t, tt.expectedUsername, u.Username, "Expected username to match")
hd, err := dei.HomeDir()
require.NoError(t, err, "Expected no error from UserHomeDir()")
require.NotEmpty(t, hd, "Expected user homedir to be non-empty")
sh, err := dei.Shell(tt.containerUser)
require.NoError(t, err, "Expected no error from UserShell()")
require.Equal(t, tt.expectedUserShell, sh, "Expected user shell to match")
// We don't need to test the actual environment variables here.
environ := dei.Environ()
require.NotEmpty(t, environ, "Expected environ to be non-empty")
// Test that the environment variables are present in modified command
// output.
envCmd, envArgs := dei.ModifyCommand("env")
for _, env := range tt.expectedEnv {
require.Subset(t, envArgs, []string{"--env", env})
}
// Run the command in the container and check the output
// HACK: we remove the --tty argument because we're not running in a tty
envArgs = slices.DeleteFunc(envArgs, func(s string) bool { return s == "--tty" })
stdout, stderr, err := run(ctx, agentexec.DefaultExecer, envCmd, envArgs...)
require.Empty(t, stderr, "Expected no stderr output")
require.NoError(t, err, "Expected no error from running command")
for _, env := range tt.expectedEnv {
require.Contains(t, stdout, env)
}
})
}
}
func run(ctx context.Context, execer agentexec.Execer, cmd string, args ...string) (stdout, stderr string, err error) {
var stdoutBuf, stderrBuf strings.Builder
execCmd := execer.CommandContext(ctx, cmd, args...)
execCmd.Stdout = &stdoutBuf
execCmd.Stderr = &stderrBuf
err = execCmd.Run()
stdout = strings.TrimSpace(stdoutBuf.String())
stderr = strings.TrimSpace(stderrBuf.String())
return stdout, stderr, err
}
+601
View File
@@ -0,0 +1,601 @@
// Code generated by dcspec/gen.sh. DO NOT EDIT.
//
// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse and unparse this JSON data, add this code to your project and do:
//
// devContainer, err := UnmarshalDevContainer(bytes)
// bytes, err = devContainer.Marshal()
package dcspec
import (
"bytes"
"errors"
)
import "encoding/json"
func UnmarshalDevContainer(data []byte) (DevContainer, error) {
var r DevContainer
err := json.Unmarshal(data, &r)
return r, err
}
func (r *DevContainer) Marshal() ([]byte, error) {
return json.Marshal(r)
}
// Defines a dev container
type DevContainer struct {
// Docker build-related options.
Build *BuildOptions `json:"build,omitempty"`
// The location of the context folder for building the Docker image. The path is relative to
// the folder containing the `devcontainer.json` file.
Context *string `json:"context,omitempty"`
// The location of the Dockerfile that defines the contents of the container. The path is
// relative to the folder containing the `devcontainer.json` file.
DockerFile *string `json:"dockerFile,omitempty"`
// The docker image that will be used to create the container.
Image *string `json:"image,omitempty"`
// Application ports that are exposed by the container. This can be a single port or an
// array of ports. Each port can be a number or a string. A number is mapped to the same
// port on the host. A string is passed to Docker unchanged and can be used to map ports
// differently, e.g. "8000:8010".
AppPort *DevContainerAppPort `json:"appPort"`
// Whether to overwrite the command specified in the image. The default is true.
//
// Whether to overwrite the command specified in the image. The default is false.
OverrideCommand *bool `json:"overrideCommand,omitempty"`
// The arguments required when starting in the container.
RunArgs []string `json:"runArgs,omitempty"`
// Action to take when the user disconnects from the container in their editor. The default
// is to stop the container.
//
// Action to take when the user disconnects from the primary container in their editor. The
// default is to stop all of the compose containers.
ShutdownAction *ShutdownAction `json:"shutdownAction,omitempty"`
// The path of the workspace folder inside the container.
//
// The path of the workspace folder inside the container. This is typically the target path
// of a volume mount in the docker-compose.yml.
WorkspaceFolder *string `json:"workspaceFolder,omitempty"`
// The --mount parameter for docker run. The default is to mount the project folder at
// /workspaces/$project.
WorkspaceMount *string `json:"workspaceMount,omitempty"`
// The name of the docker-compose file(s) used to start the services.
DockerComposeFile *CacheFrom `json:"dockerComposeFile"`
// An array of services that should be started and stopped.
RunServices []string `json:"runServices,omitempty"`
// The service you want to work on. This is considered the primary container for your dev
// environment which your editor will connect to.
Service *string `json:"service,omitempty"`
// The JSON schema of the `devcontainer.json` file.
Schema *string `json:"$schema,omitempty"`
AdditionalProperties map[string]interface{} `json:"additionalProperties,omitempty"`
// Passes docker capabilities to include when creating the dev container.
CapAdd []string `json:"capAdd,omitempty"`
// Container environment variables.
ContainerEnv map[string]string `json:"containerEnv,omitempty"`
// The user the container will be started with. The default is the user on the Docker image.
ContainerUser *string `json:"containerUser,omitempty"`
// Tool-specific configuration. Each tool should use a JSON object subproperty with a unique
// name to group its customizations.
Customizations map[string]interface{} `json:"customizations,omitempty"`
// Features to add to the dev container.
Features *Features `json:"features,omitempty"`
// Ports that are forwarded from the container to the local machine. Can be an integer port
// number, or a string of the format "host:port_number".
ForwardPorts []ForwardPort `json:"forwardPorts,omitempty"`
// Host hardware requirements.
HostRequirements *HostRequirements `json:"hostRequirements,omitempty"`
// Passes the --init flag when creating the dev container.
Init *bool `json:"init,omitempty"`
// A command to run locally (i.e Your host machine, cloud VM) before anything else. This
// command is run before "onCreateCommand". If this is a single string, it will be run in a
// shell. If this is an array of strings, it will be run as a single command without shell.
// If this is an object, each provided command will be run in parallel.
InitializeCommand *Command `json:"initializeCommand"`
// Mount points to set up when creating the container. See Docker's documentation for the
// --mount option for the supported syntax.
Mounts []MountElement `json:"mounts,omitempty"`
// A name for the dev container which can be displayed to the user.
Name *string `json:"name,omitempty"`
// A command to run when creating the container. This command is run after
// "initializeCommand" and before "updateContentCommand". If this is a single string, it
// will be run in a shell. If this is an array of strings, it will be run as a single
// command without shell. If this is an object, each provided command will be run in
// parallel.
OnCreateCommand *Command `json:"onCreateCommand"`
OtherPortsAttributes *OtherPortsAttributes `json:"otherPortsAttributes,omitempty"`
// Array consisting of the Feature id (without the semantic version) of Features in the
// order the user wants them to be installed.
OverrideFeatureInstallOrder []string `json:"overrideFeatureInstallOrder,omitempty"`
PortsAttributes *PortsAttributes `json:"portsAttributes,omitempty"`
// A command to run when attaching to the container. This command is run after
// "postStartCommand". If this is a single string, it will be run in a shell. If this is an
// array of strings, it will be run as a single command without shell. If this is an object,
// each provided command will be run in parallel.
PostAttachCommand *Command `json:"postAttachCommand"`
// A command to run after creating the container. This command is run after
// "updateContentCommand" and before "postStartCommand". If this is a single string, it will
// be run in a shell. If this is an array of strings, it will be run as a single command
// without shell. If this is an object, each provided command will be run in parallel.
PostCreateCommand *Command `json:"postCreateCommand"`
// A command to run after starting the container. This command is run after
// "postCreateCommand" and before "postAttachCommand". If this is a single string, it will
// be run in a shell. If this is an array of strings, it will be run as a single command
// without shell. If this is an object, each provided command will be run in parallel.
PostStartCommand *Command `json:"postStartCommand"`
// Passes the --privileged flag when creating the dev container.
Privileged *bool `json:"privileged,omitempty"`
// Remote environment variables to set for processes spawned in the container including
// lifecycle scripts and any remote editor/IDE server process.
RemoteEnv map[string]*string `json:"remoteEnv,omitempty"`
// The username to use for spawning processes in the container including lifecycle scripts
// and any remote editor/IDE server process. The default is the same user as the container.
RemoteUser *string `json:"remoteUser,omitempty"`
// Recommended secrets for this dev container. Recommendations are provided as environment
// variable keys with optional metadata.
Secrets *Secrets `json:"secrets,omitempty"`
// Passes docker security options to include when creating the dev container.
SecurityOpt []string `json:"securityOpt,omitempty"`
// A command to run when creating the container and rerun when the workspace content was
// updated while creating the container. This command is run after "onCreateCommand" and
// before "postCreateCommand". If this is a single string, it will be run in a shell. If
// this is an array of strings, it will be run as a single command without shell. If this is
// an object, each provided command will be run in parallel.
UpdateContentCommand *Command `json:"updateContentCommand"`
// Controls whether on Linux the container's user should be updated with the local user's
// UID and GID. On by default when opening from a local folder.
UpdateRemoteUserUID *bool `json:"updateRemoteUserUID,omitempty"`
// User environment probe to run. The default is "loginInteractiveShell".
UserEnvProbe *UserEnvProbe `json:"userEnvProbe,omitempty"`
// The user command to wait for before continuing execution in the background while the UI
// is starting up. The default is "updateContentCommand".
WaitFor *WaitFor `json:"waitFor,omitempty"`
}
// Docker build-related options.
type BuildOptions struct {
// The location of the context folder for building the Docker image. The path is relative to
// the folder containing the `devcontainer.json` file.
Context *string `json:"context,omitempty"`
// The location of the Dockerfile that defines the contents of the container. The path is
// relative to the folder containing the `devcontainer.json` file.
Dockerfile *string `json:"dockerfile,omitempty"`
// Build arguments.
Args map[string]string `json:"args,omitempty"`
// The image to consider as a cache. Use an array to specify multiple images.
CacheFrom *CacheFrom `json:"cacheFrom"`
// Additional arguments passed to the build command.
Options []string `json:"options,omitempty"`
// Target stage in a multi-stage build.
Target *string `json:"target,omitempty"`
}
// Features to add to the dev container.
type Features struct {
Fish interface{} `json:"fish"`
Gradle interface{} `json:"gradle"`
Homebrew interface{} `json:"homebrew"`
Jupyterlab interface{} `json:"jupyterlab"`
Maven interface{} `json:"maven"`
}
// Host hardware requirements.
type HostRequirements struct {
// Number of required CPUs.
Cpus *int64 `json:"cpus,omitempty"`
GPU *GPUUnion `json:"gpu"`
// Amount of required RAM in bytes. Supports units tb, gb, mb and kb.
Memory *string `json:"memory,omitempty"`
// Amount of required disk space in bytes. Supports units tb, gb, mb and kb.
Storage *string `json:"storage,omitempty"`
}
// Indicates whether a GPU is required. The string "optional" indicates that a GPU is
// optional. An object value can be used to configure more detailed requirements.
type GPUClass struct {
// Number of required cores.
Cores *int64 `json:"cores,omitempty"`
// Amount of required RAM in bytes. Supports units tb, gb, mb and kb.
Memory *string `json:"memory,omitempty"`
}
type Mount struct {
// Mount source.
Source *string `json:"source,omitempty"`
// Mount target.
Target string `json:"target"`
// Mount type.
Type Type `json:"type"`
}
type OtherPortsAttributes struct {
// Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is
// required if the local port is a privileged port.
ElevateIfNeeded *bool `json:"elevateIfNeeded,omitempty"`
// Label that will be shown in the UI for this port.
Label *string `json:"label,omitempty"`
// Defines the action that occurs when the port is discovered for automatic forwarding
OnAutoForward *OnAutoForward `json:"onAutoForward,omitempty"`
// The protocol to use when forwarding this port.
Protocol *Protocol `json:"protocol,omitempty"`
RequireLocalPort *bool `json:"requireLocalPort,omitempty"`
}
type PortsAttributes struct{}
// Recommended secrets for this dev container. Recommendations are provided as environment
// variable keys with optional metadata.
type Secrets struct{}
type GPUEnum string
const (
Optional GPUEnum = "optional"
)
// Mount type.
type Type string
const (
Bind Type = "bind"
Volume Type = "volume"
)
// Defines the action that occurs when the port is discovered for automatic forwarding
type OnAutoForward string
const (
Ignore OnAutoForward = "ignore"
Notify OnAutoForward = "notify"
OpenBrowser OnAutoForward = "openBrowser"
OpenPreview OnAutoForward = "openPreview"
Silent OnAutoForward = "silent"
)
// The protocol to use when forwarding this port.
type Protocol string
const (
HTTP Protocol = "http"
HTTPS Protocol = "https"
)
// Action to take when the user disconnects from the container in their editor. The default
// is to stop the container.
//
// Action to take when the user disconnects from the primary container in their editor. The
// default is to stop all of the compose containers.
type ShutdownAction string
const (
ShutdownActionNone ShutdownAction = "none"
StopCompose ShutdownAction = "stopCompose"
StopContainer ShutdownAction = "stopContainer"
)
// User environment probe to run. The default is "loginInteractiveShell".
type UserEnvProbe string
const (
InteractiveShell UserEnvProbe = "interactiveShell"
LoginInteractiveShell UserEnvProbe = "loginInteractiveShell"
LoginShell UserEnvProbe = "loginShell"
UserEnvProbeNone UserEnvProbe = "none"
)
// The user command to wait for before continuing execution in the background while the UI
// is starting up. The default is "updateContentCommand".
type WaitFor string
const (
InitializeCommand WaitFor = "initializeCommand"
OnCreateCommand WaitFor = "onCreateCommand"
PostCreateCommand WaitFor = "postCreateCommand"
PostStartCommand WaitFor = "postStartCommand"
UpdateContentCommand WaitFor = "updateContentCommand"
)
// Application ports that are exposed by the container. This can be a single port or an
// array of ports. Each port can be a number or a string. A number is mapped to the same
// port on the host. A string is passed to Docker unchanged and can be used to map ports
// differently, e.g. "8000:8010".
type DevContainerAppPort struct {
Integer *int64
String *string
UnionArray []AppPortElement
}
func (x *DevContainerAppPort) UnmarshalJSON(data []byte) error {
x.UnionArray = nil
object, err := unmarshalUnion(data, &x.Integer, nil, nil, &x.String, true, &x.UnionArray, false, nil, false, nil, false, nil, false)
if err != nil {
return err
}
if object {
}
return nil
}
func (x *DevContainerAppPort) MarshalJSON() ([]byte, error) {
return marshalUnion(x.Integer, nil, nil, x.String, x.UnionArray != nil, x.UnionArray, false, nil, false, nil, false, nil, false)
}
// Application ports that are exposed by the container. This can be a single port or an
// array of ports. Each port can be a number or a string. A number is mapped to the same
// port on the host. A string is passed to Docker unchanged and can be used to map ports
// differently, e.g. "8000:8010".
type AppPortElement struct {
Integer *int64
String *string
}
func (x *AppPortElement) UnmarshalJSON(data []byte) error {
object, err := unmarshalUnion(data, &x.Integer, nil, nil, &x.String, false, nil, false, nil, false, nil, false, nil, false)
if err != nil {
return err
}
if object {
}
return nil
}
func (x *AppPortElement) MarshalJSON() ([]byte, error) {
return marshalUnion(x.Integer, nil, nil, x.String, false, nil, false, nil, false, nil, false, nil, false)
}
// The image to consider as a cache. Use an array to specify multiple images.
//
// The name of the docker-compose file(s) used to start the services.
type CacheFrom struct {
String *string
StringArray []string
}
func (x *CacheFrom) UnmarshalJSON(data []byte) error {
x.StringArray = nil
object, err := unmarshalUnion(data, nil, nil, nil, &x.String, true, &x.StringArray, false, nil, false, nil, false, nil, false)
if err != nil {
return err
}
if object {
}
return nil
}
func (x *CacheFrom) MarshalJSON() ([]byte, error) {
return marshalUnion(nil, nil, nil, x.String, x.StringArray != nil, x.StringArray, false, nil, false, nil, false, nil, false)
}
type ForwardPort struct {
Integer *int64
String *string
}
func (x *ForwardPort) UnmarshalJSON(data []byte) error {
object, err := unmarshalUnion(data, &x.Integer, nil, nil, &x.String, false, nil, false, nil, false, nil, false, nil, false)
if err != nil {
return err
}
if object {
}
return nil
}
func (x *ForwardPort) MarshalJSON() ([]byte, error) {
return marshalUnion(x.Integer, nil, nil, x.String, false, nil, false, nil, false, nil, false, nil, false)
}
type GPUUnion struct {
Bool *bool
Enum *GPUEnum
GPUClass *GPUClass
}
func (x *GPUUnion) UnmarshalJSON(data []byte) error {
x.GPUClass = nil
x.Enum = nil
var c GPUClass
object, err := unmarshalUnion(data, nil, nil, &x.Bool, nil, false, nil, true, &c, false, nil, true, &x.Enum, false)
if err != nil {
return err
}
if object {
x.GPUClass = &c
}
return nil
}
func (x *GPUUnion) MarshalJSON() ([]byte, error) {
return marshalUnion(nil, nil, x.Bool, nil, false, nil, x.GPUClass != nil, x.GPUClass, false, nil, x.Enum != nil, x.Enum, false)
}
// A command to run locally (i.e Your host machine, cloud VM) before anything else. This
// command is run before "onCreateCommand". If this is a single string, it will be run in a
// shell. If this is an array of strings, it will be run as a single command without shell.
// If this is an object, each provided command will be run in parallel.
//
// A command to run when creating the container. This command is run after
// "initializeCommand" and before "updateContentCommand". If this is a single string, it
// will be run in a shell. If this is an array of strings, it will be run as a single
// command without shell. If this is an object, each provided command will be run in
// parallel.
//
// A command to run when attaching to the container. This command is run after
// "postStartCommand". If this is a single string, it will be run in a shell. If this is an
// array of strings, it will be run as a single command without shell. If this is an object,
// each provided command will be run in parallel.
//
// A command to run after creating the container. This command is run after
// "updateContentCommand" and before "postStartCommand". If this is a single string, it will
// be run in a shell. If this is an array of strings, it will be run as a single command
// without shell. If this is an object, each provided command will be run in parallel.
//
// A command to run after starting the container. This command is run after
// "postCreateCommand" and before "postAttachCommand". If this is a single string, it will
// be run in a shell. If this is an array of strings, it will be run as a single command
// without shell. If this is an object, each provided command will be run in parallel.
//
// A command to run when creating the container and rerun when the workspace content was
// updated while creating the container. This command is run after "onCreateCommand" and
// before "postCreateCommand". If this is a single string, it will be run in a shell. If
// this is an array of strings, it will be run as a single command without shell. If this is
// an object, each provided command will be run in parallel.
type Command struct {
String *string
StringArray []string
UnionMap map[string]*CacheFrom
}
func (x *Command) UnmarshalJSON(data []byte) error {
x.StringArray = nil
x.UnionMap = nil
object, err := unmarshalUnion(data, nil, nil, nil, &x.String, true, &x.StringArray, false, nil, true, &x.UnionMap, false, nil, false)
if err != nil {
return err
}
if object {
}
return nil
}
func (x *Command) MarshalJSON() ([]byte, error) {
return marshalUnion(nil, nil, nil, x.String, x.StringArray != nil, x.StringArray, false, nil, x.UnionMap != nil, x.UnionMap, false, nil, false)
}
type MountElement struct {
Mount *Mount
String *string
}
func (x *MountElement) UnmarshalJSON(data []byte) error {
x.Mount = nil
var c Mount
object, err := unmarshalUnion(data, nil, nil, nil, &x.String, false, nil, true, &c, false, nil, false, nil, false)
if err != nil {
return err
}
if object {
x.Mount = &c
}
return nil
}
func (x *MountElement) MarshalJSON() ([]byte, error) {
return marshalUnion(nil, nil, nil, x.String, false, nil, x.Mount != nil, x.Mount, false, nil, false, nil, false)
}
func unmarshalUnion(data []byte, pi **int64, pf **float64, pb **bool, ps **string, haveArray bool, pa interface{}, haveObject bool, pc interface{}, haveMap bool, pm interface{}, haveEnum bool, pe interface{}, nullable bool) (bool, error) {
if pi != nil {
*pi = nil
}
if pf != nil {
*pf = nil
}
if pb != nil {
*pb = nil
}
if ps != nil {
*ps = nil
}
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
tok, err := dec.Token()
if err != nil {
return false, err
}
switch v := tok.(type) {
case json.Number:
if pi != nil {
i, err := v.Int64()
if err == nil {
*pi = &i
return false, nil
}
}
if pf != nil {
f, err := v.Float64()
if err == nil {
*pf = &f
return false, nil
}
return false, errors.New("Unparsable number")
}
return false, errors.New("Union does not contain number")
case float64:
return false, errors.New("Decoder should not return float64")
case bool:
if pb != nil {
*pb = &v
return false, nil
}
return false, errors.New("Union does not contain bool")
case string:
if haveEnum {
return false, json.Unmarshal(data, pe)
}
if ps != nil {
*ps = &v
return false, nil
}
return false, errors.New("Union does not contain string")
case nil:
if nullable {
return false, nil
}
return false, errors.New("Union does not contain null")
case json.Delim:
if v == '{' {
if haveObject {
return true, json.Unmarshal(data, pc)
}
if haveMap {
return false, json.Unmarshal(data, pm)
}
return false, errors.New("Union does not contain object")
}
if v == '[' {
if haveArray {
return false, json.Unmarshal(data, pa)
}
return false, errors.New("Union does not contain array")
}
return false, errors.New("Cannot handle delimiter")
}
return false, errors.New("Cannot unmarshal union")
}
func marshalUnion(pi *int64, pf *float64, pb *bool, ps *string, haveArray bool, pa interface{}, haveObject bool, pc interface{}, haveMap bool, pm interface{}, haveEnum bool, pe interface{}, nullable bool) ([]byte, error) {
if pi != nil {
return json.Marshal(*pi)
}
if pf != nil {
return json.Marshal(*pf)
}
if pb != nil {
return json.Marshal(*pb)
}
if ps != nil {
return json.Marshal(*ps)
}
if haveArray {
return json.Marshal(pa)
}
if haveObject {
return json.Marshal(pc)
}
if haveMap {
return json.Marshal(pm)
}
if haveEnum {
return json.Marshal(pe)
}
if nullable {
return json.Marshal(nil)
}
return nil, errors.New("Union must not be null")
}
+148
View File
@@ -0,0 +1,148 @@
package dcspec_test
import (
"encoding/json"
"os"
"path/filepath"
"slices"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/agent/agentcontainers/dcspec"
"github.com/coder/coder/v2/coderd/util/ptr"
)
func TestUnmarshalDevContainer(t *testing.T) {
t.Parallel()
type testCase struct {
name string
file string
wantErr bool
want dcspec.DevContainer
}
tests := []testCase{
{
name: "minimal",
file: filepath.Join("testdata", "minimal.json"),
want: dcspec.DevContainer{
Image: ptr.Ref("test-image"),
},
},
{
name: "arrays",
file: filepath.Join("testdata", "arrays.json"),
want: dcspec.DevContainer{
Image: ptr.Ref("test-image"),
RunArgs: []string{"--network=host", "--privileged"},
ForwardPorts: []dcspec.ForwardPort{
{
Integer: ptr.Ref[int64](8080),
},
{
String: ptr.Ref("3000:3000"),
},
},
},
},
{
name: "devcontainers/template-starter",
file: filepath.Join("testdata", "devcontainers-template-starter.json"),
wantErr: false,
want: dcspec.DevContainer{
Image: ptr.Ref("mcr.microsoft.com/devcontainers/javascript-node:1-18-bullseye"),
Features: &dcspec.Features{},
Customizations: map[string]interface{}{
"vscode": map[string]interface{}{
"extensions": []interface{}{
"mads-hartmann.bash-ide-vscode",
"dbaeumer.vscode-eslint",
},
},
},
PostCreateCommand: &dcspec.Command{
String: ptr.Ref("npm install -g @devcontainers/cli"),
},
},
},
}
var missingTests []string
files, err := filepath.Glob("testdata/*.json")
require.NoError(t, err, "glob test files failed")
for _, file := range files {
if !slices.ContainsFunc(tests, func(tt testCase) bool {
return tt.file == file
}) {
missingTests = append(missingTests, file)
}
}
require.Empty(t, missingTests, "missing tests case for files: %v", missingTests)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
data, err := os.ReadFile(tt.file)
require.NoError(t, err, "read test file failed")
got, err := dcspec.UnmarshalDevContainer(data)
if tt.wantErr {
require.Error(t, err, "want error but got nil")
return
}
require.NoError(t, err, "unmarshal DevContainer failed")
// Compare the unmarshaled data with the expected data.
if diff := cmp.Diff(tt.want, got); diff != "" {
require.Empty(t, diff, "UnmarshalDevContainer() mismatch (-want +got):\n%s", diff)
}
// Test that marshaling works (without comparing to original).
marshaled, err := got.Marshal()
require.NoError(t, err, "marshal DevContainer back to JSON failed")
require.NotEmpty(t, marshaled, "marshaled JSON should not be empty")
// Verify the marshaled JSON can be unmarshaled back.
var unmarshaled interface{}
err = json.Unmarshal(marshaled, &unmarshaled)
require.NoError(t, err, "unmarshal marshaled JSON failed")
})
}
}
func TestUnmarshalDevContainer_EdgeCases(t *testing.T) {
t.Parallel()
tests := []struct {
name string
json string
wantErr bool
}{
{
name: "empty JSON",
json: "{}",
wantErr: false,
},
{
name: "invalid JSON",
json: "{not valid json",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
_, err := dcspec.UnmarshalDevContainer([]byte(tt.json))
if tt.wantErr {
require.Error(t, err, "want error but got nil")
return
}
require.NoError(t, err, "unmarshal DevContainer failed")
})
}
}
@@ -0,0 +1,771 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"description": "Defines a dev container",
"allowComments": true,
"allowTrailingCommas": false,
"definitions": {
"devContainerCommon": {
"type": "object",
"properties": {
"$schema": {
"type": "string",
"format": "uri",
"description": "The JSON schema of the `devcontainer.json` file."
},
"name": {
"type": "string",
"description": "A name for the dev container which can be displayed to the user."
},
"features": {
"type": "object",
"description": "Features to add to the dev container.",
"properties": {
"fish": {
"deprecated": true,
"deprecationMessage": "Legacy feature not supported. Please check https://containers.dev/features for replacements."
},
"maven": {
"deprecated": true,
"deprecationMessage": "Legacy feature will be removed in the future. Please check https://containers.dev/features for replacements. E.g., `ghcr.io/devcontainers/features/java` has an option to install Maven."
},
"gradle": {
"deprecated": true,
"deprecationMessage": "Legacy feature will be removed in the future. Please check https://containers.dev/features for replacements. E.g., `ghcr.io/devcontainers/features/java` has an option to install Gradle."
},
"homebrew": {
"deprecated": true,
"deprecationMessage": "Legacy feature not supported. Please check https://containers.dev/features for replacements."
},
"jupyterlab": {
"deprecated": true,
"deprecationMessage": "Legacy feature will be removed in the future. Please check https://containers.dev/features for replacements. E.g., `ghcr.io/devcontainers/features/python` has an option to install JupyterLab."
}
},
"additionalProperties": true
},
"overrideFeatureInstallOrder": {
"type": "array",
"description": "Array consisting of the Feature id (without the semantic version) of Features in the order the user wants them to be installed.",
"items": {
"type": "string"
}
},
"secrets": {
"type": "object",
"description": "Recommended secrets for this dev container. Recommendations are provided as environment variable keys with optional metadata.",
"patternProperties": {
"^[a-zA-Z_][a-zA-Z0-9_]*$": {
"type": "object",
"description": "Environment variable keys following unix-style naming conventions. eg: ^[a-zA-Z_][a-zA-Z0-9_]*$",
"properties": {
"description": {
"type": "string",
"description": "A description of the secret."
},
"documentationUrl": {
"type": "string",
"format": "uri",
"description": "A URL to documentation about the secret."
}
},
"additionalProperties": false
},
"additionalProperties": false
},
"additionalProperties": false
},
"forwardPorts": {
"type": "array",
"description": "Ports that are forwarded from the container to the local machine. Can be an integer port number, or a string of the format \"host:port_number\".",
"items": {
"oneOf": [
{
"type": "integer",
"maximum": 65535,
"minimum": 0
},
{
"type": "string",
"pattern": "^([a-z0-9-]+):(\\d{1,5})$"
}
]
}
},
"portsAttributes": {
"type": "object",
"patternProperties": {
"(^\\d+(-\\d+)?$)|(.+)": {
"type": "object",
"description": "A port, range of ports (ex. \"40000-55000\"), or regular expression (ex. \".+\\\\/server.js\"). For a port number or range, the attributes will apply to that port number or range of port numbers. Attributes which use a regular expression will apply to ports whose associated process command line matches the expression.",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openBrowserOnce",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens the browser when the port is automatically forwarded, but only the first time the port is forward during a session. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
"label": "Application",
"onAutoForward": "notify"
}
}
},
"markdownDescription": "Set default properties that are applied when a specific port number is forwarded. For example:\n\n```\n\"3000\": {\n \"label\": \"Application\"\n},\n\"40000-55000\": {\n \"onAutoForward\": \"ignore\"\n},\n\".+\\\\/server.js\": {\n \"onAutoForward\": \"openPreview\"\n}\n```",
"defaultSnippets": [
{
"body": {
"${1:3000}": {
"label": "${2:Application}",
"onAutoForward": "notify"
}
}
}
],
"additionalProperties": false
},
"otherPortsAttributes": {
"type": "object",
"properties": {
"onAutoForward": {
"type": "string",
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
"Opens a preview in the same window when the port is automatically forwarded.",
"Shows no notification and takes no action when this port is automatically forwarded.",
"This port will not be automatically forwarded."
],
"description": "Defines the action that occurs when the port is discovered for automatic forwarding",
"default": "notify"
},
"elevateIfNeeded": {
"type": "boolean",
"description": "Automatically prompt for elevation (if needed) when this port is forwarded. Elevate is required if the local port is a privileged port.",
"default": false
},
"label": {
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [
{
"body": {
"onAutoForward": "ignore"
}
}
],
"markdownDescription": "Set default properties that are applied to all ports that don't get properties from the setting `remote.portsAttributes`. For example:\n\n```\n{\n \"onAutoForward\": \"ignore\"\n}\n```",
"additionalProperties": false
},
"updateRemoteUserUID": {
"type": "boolean",
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default when opening from a local folder."
},
"containerEnv": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Container environment variables."
},
"containerUser": {
"type": "string",
"description": "The user the container will be started with. The default is the user on the Docker image."
},
"mounts": {
"type": "array",
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
"items": {
"anyOf": [
{
"$ref": "#/definitions/Mount"
},
{
"type": "string"
}
]
}
},
"init": {
"type": "boolean",
"description": "Passes the --init flag when creating the dev container."
},
"privileged": {
"type": "boolean",
"description": "Passes the --privileged flag when creating the dev container."
},
"capAdd": {
"type": "array",
"description": "Passes docker capabilities to include when creating the dev container.",
"examples": [
"SYS_PTRACE"
],
"items": {
"type": "string"
}
},
"securityOpt": {
"type": "array",
"description": "Passes docker security options to include when creating the dev container.",
"examples": [
"seccomp=unconfined"
],
"items": {
"type": "string"
}
},
"remoteEnv": {
"type": "object",
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Remote environment variables to set for processes spawned in the container including lifecycle scripts and any remote editor/IDE server process."
},
"remoteUser": {
"type": "string",
"description": "The username to use for spawning processes in the container including lifecycle scripts and any remote editor/IDE server process. The default is the same user as the container."
},
"initializeCommand": {
"type": [
"string",
"array",
"object"
],
"description": "A command to run locally (i.e Your host machine, cloud VM) before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell. If this is an object, each provided command will be run in parallel.",
"items": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
}
},
"onCreateCommand": {
"type": [
"string",
"array",
"object"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell. If this is an object, each provided command will be run in parallel.",
"items": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
}
},
"updateContentCommand": {
"type": [
"string",
"array",
"object"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell. If this is an object, each provided command will be run in parallel.",
"items": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
}
},
"postCreateCommand": {
"type": [
"string",
"array",
"object"
],
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell. If this is an object, each provided command will be run in parallel.",
"items": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
}
},
"postStartCommand": {
"type": [
"string",
"array",
"object"
],
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell. If this is an object, each provided command will be run in parallel.",
"items": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
}
},
"postAttachCommand": {
"type": [
"string",
"array",
"object"
],
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell. If this is an object, each provided command will be run in parallel.",
"items": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
}
},
"waitFor": {
"type": "string",
"enum": [
"initializeCommand",
"onCreateCommand",
"updateContentCommand",
"postCreateCommand",
"postStartCommand"
],
"description": "The user command to wait for before continuing execution in the background while the UI is starting up. The default is \"updateContentCommand\"."
},
"userEnvProbe": {
"type": "string",
"enum": [
"none",
"loginShell",
"loginInteractiveShell",
"interactiveShell"
],
"description": "User environment probe to run. The default is \"loginInteractiveShell\"."
},
"hostRequirements": {
"type": "object",
"description": "Host hardware requirements.",
"properties": {
"cpus": {
"type": "integer",
"minimum": 1,
"description": "Number of required CPUs."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
},
"storage": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
},
"gpu": {
"oneOf": [
{
"type": [
"boolean",
"string"
],
"enum": [
true,
false,
"optional"
],
"description": "Indicates whether a GPU is required. The string \"optional\" indicates that a GPU is optional. An object value can be used to configure more detailed requirements."
},
{
"type": "object",
"properties": {
"cores": {
"type": "integer",
"minimum": 1,
"description": "Number of required cores."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
}
},
"description": "Indicates whether a GPU is required. The string \"optional\" indicates that a GPU is optional. An object value can be used to configure more detailed requirements.",
"additionalProperties": false
}
]
}
},
"unevaluatedProperties": false
},
"customizations": {
"type": "object",
"description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations."
},
"additionalProperties": {
"type": "object",
"additionalProperties": true
}
}
},
"nonComposeBase": {
"type": "object",
"properties": {
"appPort": {
"type": [
"integer",
"string",
"array"
],
"description": "Application ports that are exposed by the container. This can be a single port or an array of ports. Each port can be a number or a string. A number is mapped to the same port on the host. A string is passed to Docker unchanged and can be used to map ports differently, e.g. \"8000:8010\".",
"items": {
"type": [
"integer",
"string"
]
}
},
"runArgs": {
"type": "array",
"description": "The arguments required when starting in the container.",
"items": {
"type": "string"
}
},
"shutdownAction": {
"type": "string",
"enum": [
"none",
"stopContainer"
],
"description": "Action to take when the user disconnects from the container in their editor. The default is to stop the container."
},
"overrideCommand": {
"type": "boolean",
"description": "Whether to overwrite the command specified in the image. The default is true."
},
"workspaceFolder": {
"type": "string",
"description": "The path of the workspace folder inside the container."
},
"workspaceMount": {
"type": "string",
"description": "The --mount parameter for docker run. The default is to mount the project folder at /workspaces/$project."
}
}
},
"dockerfileContainer": {
"oneOf": [
{
"type": "object",
"properties": {
"build": {
"type": "object",
"description": "Docker build-related options.",
"allOf": [
{
"type": "object",
"properties": {
"dockerfile": {
"type": "string",
"description": "The location of the Dockerfile that defines the contents of the container. The path is relative to the folder containing the `devcontainer.json` file."
},
"context": {
"type": "string",
"description": "The location of the context folder for building the Docker image. The path is relative to the folder containing the `devcontainer.json` file."
}
},
"required": [
"dockerfile"
]
},
{
"$ref": "#/definitions/buildOptions"
}
],
"unevaluatedProperties": false
}
},
"required": [
"build"
]
},
{
"allOf": [
{
"type": "object",
"properties": {
"dockerFile": {
"type": "string",
"description": "The location of the Dockerfile that defines the contents of the container. The path is relative to the folder containing the `devcontainer.json` file."
},
"context": {
"type": "string",
"description": "The location of the context folder for building the Docker image. The path is relative to the folder containing the `devcontainer.json` file."
}
},
"required": [
"dockerFile"
]
},
{
"type": "object",
"properties": {
"build": {
"description": "Docker build-related options.",
"$ref": "#/definitions/buildOptions"
}
}
}
]
}
]
},
"buildOptions": {
"type": "object",
"properties": {
"target": {
"type": "string",
"description": "Target stage in a multi-stage build."
},
"args": {
"type": "object",
"additionalProperties": {
"type": [
"string"
]
},
"description": "Build arguments."
},
"cacheFrom": {
"type": [
"string",
"array"
],
"description": "The image to consider as a cache. Use an array to specify multiple images.",
"items": {
"type": "string"
}
},
"options": {
"type": "array",
"description": "Additional arguments passed to the build command.",
"items": {
"type": "string"
}
}
}
},
"imageContainer": {
"type": "object",
"properties": {
"image": {
"type": "string",
"description": "The docker image that will be used to create the container."
}
},
"required": [
"image"
]
},
"composeContainer": {
"type": "object",
"properties": {
"dockerComposeFile": {
"type": [
"string",
"array"
],
"description": "The name of the docker-compose file(s) used to start the services.",
"items": {
"type": "string"
}
},
"service": {
"type": "string",
"description": "The service you want to work on. This is considered the primary container for your dev environment which your editor will connect to."
},
"runServices": {
"type": "array",
"description": "An array of services that should be started and stopped.",
"items": {
"type": "string"
}
},
"workspaceFolder": {
"type": "string",
"description": "The path of the workspace folder inside the container. This is typically the target path of a volume mount in the docker-compose.yml."
},
"shutdownAction": {
"type": "string",
"enum": [
"none",
"stopCompose"
],
"description": "Action to take when the user disconnects from the primary container in their editor. The default is to stop all of the compose containers."
},
"overrideCommand": {
"type": "boolean",
"description": "Whether to overwrite the command specified in the image. The default is false."
}
},
"required": [
"dockerComposeFile",
"service",
"workspaceFolder"
]
},
"Mount": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"bind",
"volume"
],
"description": "Mount type."
},
"source": {
"type": "string",
"description": "Mount source."
},
"target": {
"type": "string",
"description": "Mount target."
}
},
"required": [
"type",
"target"
],
"additionalProperties": false
}
},
"oneOf": [
{
"allOf": [
{
"oneOf": [
{
"allOf": [
{
"oneOf": [
{
"$ref": "#/definitions/dockerfileContainer"
},
{
"$ref": "#/definitions/imageContainer"
}
]
},
{
"$ref": "#/definitions/nonComposeBase"
}
]
},
{
"$ref": "#/definitions/composeContainer"
}
]
},
{
"$ref": "#/definitions/devContainerCommon"
}
]
},
{
"type": "object",
"$ref": "#/definitions/devContainerCommon",
"additionalProperties": false
}
],
"unevaluatedProperties": false
}
+5
View File
@@ -0,0 +1,5 @@
// Package dcspec contains an automatically generated Devcontainer
// specification.
package dcspec
//go:generate ./gen.sh
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
set -euo pipefail
# This script requires quicktype to be installed.
# While you can install it using npm, we have it in our devDependencies
# in ${PROJECT_ROOT}/package.json.
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
if ! pnpm list | grep quicktype &>/dev/null; then
echo "quicktype is required to run this script!"
echo "Ensure that it is present in the devDependencies of ${PROJECT_ROOT}/package.json and then run pnpm install."
exit 1
fi
DEST_FILENAME="dcspec_gen.go"
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
DEST_PATH="${SCRIPT_DIR}/${DEST_FILENAME}"
# Location of the JSON schema for the devcontainer specification.
SCHEMA_SRC="https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.base.schema.json"
SCHEMA_DEST="${SCRIPT_DIR}/devContainer.base.schema.json"
UPDATE_SCHEMA="${UPDATE_SCHEMA:-false}"
if [[ "${UPDATE_SCHEMA}" = true || ! -f "${SCHEMA_DEST}" ]]; then
# Download the latest schema.
echo "Updating schema..."
curl --fail --silent --show-error --location --output "${SCHEMA_DEST}" "${SCHEMA_SRC}"
else
echo "Using existing schema..."
fi
TMPDIR=$(mktemp -d)
trap 'rm -rfv "$TMPDIR"' EXIT
show_stderr=1
exec 3>&2
if [[ " $* " == *" --quiet "* ]] || [[ ${DCSPEC_QUIET:-false} == "true" ]]; then
# Redirect stderr to log because quicktype can't infer all types and
# we don't care right now.
show_stderr=0
exec 2>"${TMPDIR}/stderr.log"
fi
if ! pnpm exec quicktype \
--src-lang schema \
--lang go \
--top-level "DevContainer" \
--out "${TMPDIR}/${DEST_FILENAME}" \
--package "dcspec" \
"${SCHEMA_DEST}"; then
echo "quicktype failed to generate Go code." >&3
if [[ "${show_stderr}" -eq 1 ]]; then
cat "${TMPDIR}/stderr.log" >&3
fi
exit 1
fi
if [[ "${show_stderr}" -eq 0 ]]; then
# Restore stderr.
exec 2>&3
fi
exec 3>&-
# Format the generated code.
go run mvdan.cc/gofumpt@v0.4.0 -w -l "${TMPDIR}/${DEST_FILENAME}"
# Add a header so that Go recognizes this as a generated file.
if grep -q -- "\[-i extension\]" < <(sed -h 2>&1); then
# darwin sed
sed -i '' '1s/^/\/\/ Code generated by dcspec\/gen.sh. DO NOT EDIT.\n\/\/\n/' "${TMPDIR}/${DEST_FILENAME}"
else
sed -i'' '1s/^/\/\/ Code generated by dcspec\/gen.sh. DO NOT EDIT.\n\/\/\n/' "${TMPDIR}/${DEST_FILENAME}"
fi
mv -v "${TMPDIR}/${DEST_FILENAME}" "${DEST_PATH}"
+5
View File
@@ -0,0 +1,5 @@
{
"image": "test-image",
"runArgs": ["--network=host", "--privileged"],
"forwardPorts": [8080, "3000:3000"]
}
@@ -0,0 +1,12 @@
{
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bullseye",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
},
"customizations": {
"vscode": {
"extensions": ["mads-hartmann.bash-ide-vscode", "dbaeumer.vscode-eslint"]
}
},
"postCreateCommand": "npm install -g @devcontainers/cli"
}
+1
View File
@@ -0,0 +1 @@
{ "image": "test-image" }
+119
View File
@@ -0,0 +1,119 @@
package agentcontainers
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"cdr.dev/slog"
"github.com/coder/coder/v2/codersdk"
)
const (
// DevcontainerLocalFolderLabel is the label that contains the path to
// the local workspace folder for a devcontainer.
DevcontainerLocalFolderLabel = "devcontainer.local_folder"
// DevcontainerConfigFileLabel is the label that contains the path to
// the devcontainer.json configuration file.
DevcontainerConfigFileLabel = "devcontainer.config_file"
)
const devcontainerUpScriptTemplate = `
if ! which devcontainer > /dev/null 2>&1; then
echo "ERROR: Unable to start devcontainer, @devcontainers/cli is not installed or not found in \$PATH." 1>&2
echo "Please install @devcontainers/cli by running \"npm install -g @devcontainers/cli\" or by using the \"devcontainers-cli\" Coder module." 1>&2
exit 1
fi
devcontainer up %s
`
// ExtractAndInitializeDevcontainerScripts extracts devcontainer scripts from
// the given scripts and devcontainers. The devcontainer scripts are removed
// from the returned scripts so that they can be run separately.
//
// Dev Containers have an inherent dependency on start scripts, since they
// initialize the workspace (e.g. git clone, npm install, etc). This is
// important if e.g. a Coder module to install @devcontainer/cli is used.
func ExtractAndInitializeDevcontainerScripts(
devcontainers []codersdk.WorkspaceAgentDevcontainer,
scripts []codersdk.WorkspaceAgentScript,
) (filteredScripts []codersdk.WorkspaceAgentScript, devcontainerScripts []codersdk.WorkspaceAgentScript) {
ScriptLoop:
for _, script := range scripts {
for _, dc := range devcontainers {
// The devcontainer scripts match the devcontainer ID for
// identification.
if script.ID == dc.ID {
devcontainerScripts = append(devcontainerScripts, devcontainerStartupScript(dc, script))
continue ScriptLoop
}
}
filteredScripts = append(filteredScripts, script)
}
return filteredScripts, devcontainerScripts
}
func devcontainerStartupScript(dc codersdk.WorkspaceAgentDevcontainer, script codersdk.WorkspaceAgentScript) codersdk.WorkspaceAgentScript {
args := []string{
"--log-format json",
fmt.Sprintf("--workspace-folder %q", dc.WorkspaceFolder),
}
if dc.ConfigPath != "" {
args = append(args, fmt.Sprintf("--config %q", dc.ConfigPath))
}
cmd := fmt.Sprintf(devcontainerUpScriptTemplate, strings.Join(args, " "))
// Force the script to run in /bin/sh, since some shells (e.g. fish)
// don't support the script.
script.Script = fmt.Sprintf("/bin/sh -c '%s'", cmd)
// Disable RunOnStart, scripts have this set so that when devcontainers
// have not been enabled, a warning will be surfaced in the agent logs.
script.RunOnStart = false
return script
}
// ExpandAllDevcontainerPaths expands all devcontainer paths in the given
// devcontainers. This is required by the devcontainer CLI, which requires
// absolute paths for the workspace folder and config path.
func ExpandAllDevcontainerPaths(logger slog.Logger, expandPath func(string) (string, error), devcontainers []codersdk.WorkspaceAgentDevcontainer) []codersdk.WorkspaceAgentDevcontainer {
expanded := make([]codersdk.WorkspaceAgentDevcontainer, 0, len(devcontainers))
for _, dc := range devcontainers {
expanded = append(expanded, expandDevcontainerPaths(logger, expandPath, dc))
}
return expanded
}
func expandDevcontainerPaths(logger slog.Logger, expandPath func(string) (string, error), dc codersdk.WorkspaceAgentDevcontainer) codersdk.WorkspaceAgentDevcontainer {
logger = logger.With(slog.F("devcontainer", dc.Name), slog.F("workspace_folder", dc.WorkspaceFolder), slog.F("config_path", dc.ConfigPath))
if wf, err := expandPath(dc.WorkspaceFolder); err != nil {
logger.Warn(context.Background(), "expand devcontainer workspace folder failed", slog.Error(err))
} else {
dc.WorkspaceFolder = wf
}
if dc.ConfigPath != "" {
// Let expandPath handle home directory, otherwise assume relative to
// workspace folder or absolute.
if dc.ConfigPath[0] == '~' {
if cp, err := expandPath(dc.ConfigPath); err != nil {
logger.Warn(context.Background(), "expand devcontainer config path failed", slog.Error(err))
} else {
dc.ConfigPath = cp
}
} else {
dc.ConfigPath = relativePathToAbs(dc.WorkspaceFolder, dc.ConfigPath)
}
}
return dc
}
func relativePathToAbs(workdir, path string) string {
path = os.ExpandEnv(path)
if !filepath.IsAbs(path) {
path = filepath.Join(workdir, path)
}
return path
}
+274
View File
@@ -0,0 +1,274 @@
package agentcontainers_test
import (
"path/filepath"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/agent/agentcontainers"
"github.com/coder/coder/v2/codersdk"
)
func TestExtractAndInitializeDevcontainerScripts(t *testing.T) {
t.Parallel()
scriptIDs := []uuid.UUID{uuid.New(), uuid.New()}
devcontainerIDs := []uuid.UUID{uuid.New(), uuid.New()}
type args struct {
expandPath func(string) (string, error)
devcontainers []codersdk.WorkspaceAgentDevcontainer
scripts []codersdk.WorkspaceAgentScript
}
tests := []struct {
name string
args args
wantFilteredScripts []codersdk.WorkspaceAgentScript
wantDevcontainerScripts []codersdk.WorkspaceAgentScript
skipOnWindowsDueToPathSeparator bool
}{
{
name: "no scripts",
args: args{
expandPath: nil,
devcontainers: nil,
scripts: nil,
},
wantFilteredScripts: nil,
wantDevcontainerScripts: nil,
},
{
name: "no devcontainers",
args: args{
expandPath: nil,
devcontainers: nil,
scripts: []codersdk.WorkspaceAgentScript{
{ID: scriptIDs[0]},
{ID: scriptIDs[1]},
},
},
wantFilteredScripts: []codersdk.WorkspaceAgentScript{
{ID: scriptIDs[0]},
{ID: scriptIDs[1]},
},
wantDevcontainerScripts: nil,
},
{
name: "no scripts match devcontainers",
args: args{
expandPath: nil,
devcontainers: []codersdk.WorkspaceAgentDevcontainer{
{ID: devcontainerIDs[0]},
{ID: devcontainerIDs[1]},
},
scripts: []codersdk.WorkspaceAgentScript{
{ID: scriptIDs[0]},
{ID: scriptIDs[1]},
},
},
wantFilteredScripts: []codersdk.WorkspaceAgentScript{
{ID: scriptIDs[0]},
{ID: scriptIDs[1]},
},
wantDevcontainerScripts: nil,
},
{
name: "scripts match devcontainers and sets RunOnStart=false",
args: args{
expandPath: nil,
devcontainers: []codersdk.WorkspaceAgentDevcontainer{
{ID: devcontainerIDs[0], WorkspaceFolder: "workspace1"},
{ID: devcontainerIDs[1], WorkspaceFolder: "workspace2"},
},
scripts: []codersdk.WorkspaceAgentScript{
{ID: scriptIDs[0], RunOnStart: true},
{ID: scriptIDs[1], RunOnStart: true},
{ID: devcontainerIDs[0], RunOnStart: true},
{ID: devcontainerIDs[1], RunOnStart: true},
},
},
wantFilteredScripts: []codersdk.WorkspaceAgentScript{
{ID: scriptIDs[0], RunOnStart: true},
{ID: scriptIDs[1], RunOnStart: true},
},
wantDevcontainerScripts: []codersdk.WorkspaceAgentScript{
{
ID: devcontainerIDs[0],
Script: "devcontainer up --log-format json --workspace-folder \"workspace1\"",
RunOnStart: false,
},
{
ID: devcontainerIDs[1],
Script: "devcontainer up --log-format json --workspace-folder \"workspace2\"",
RunOnStart: false,
},
},
},
{
name: "scripts match devcontainers with config path",
args: args{
expandPath: nil,
devcontainers: []codersdk.WorkspaceAgentDevcontainer{
{
ID: devcontainerIDs[0],
WorkspaceFolder: "workspace1",
ConfigPath: "config1",
},
{
ID: devcontainerIDs[1],
WorkspaceFolder: "workspace2",
ConfigPath: "config2",
},
},
scripts: []codersdk.WorkspaceAgentScript{
{ID: devcontainerIDs[0]},
{ID: devcontainerIDs[1]},
},
},
wantFilteredScripts: []codersdk.WorkspaceAgentScript{},
wantDevcontainerScripts: []codersdk.WorkspaceAgentScript{
{
ID: devcontainerIDs[0],
Script: "devcontainer up --log-format json --workspace-folder \"workspace1\" --config \"workspace1/config1\"",
RunOnStart: false,
},
{
ID: devcontainerIDs[1],
Script: "devcontainer up --log-format json --workspace-folder \"workspace2\" --config \"workspace2/config2\"",
RunOnStart: false,
},
},
skipOnWindowsDueToPathSeparator: true,
},
{
name: "scripts match devcontainers with expand path",
args: args{
expandPath: func(s string) (string, error) {
return "/home/" + s, nil
},
devcontainers: []codersdk.WorkspaceAgentDevcontainer{
{
ID: devcontainerIDs[0],
WorkspaceFolder: "workspace1",
ConfigPath: "config1",
},
{
ID: devcontainerIDs[1],
WorkspaceFolder: "workspace2",
ConfigPath: "config2",
},
},
scripts: []codersdk.WorkspaceAgentScript{
{ID: devcontainerIDs[0], RunOnStart: true},
{ID: devcontainerIDs[1], RunOnStart: true},
},
},
wantFilteredScripts: []codersdk.WorkspaceAgentScript{},
wantDevcontainerScripts: []codersdk.WorkspaceAgentScript{
{
ID: devcontainerIDs[0],
Script: "devcontainer up --log-format json --workspace-folder \"/home/workspace1\" --config \"/home/workspace1/config1\"",
RunOnStart: false,
},
{
ID: devcontainerIDs[1],
Script: "devcontainer up --log-format json --workspace-folder \"/home/workspace2\" --config \"/home/workspace2/config2\"",
RunOnStart: false,
},
},
skipOnWindowsDueToPathSeparator: true,
},
{
name: "expand config path when ~",
args: args{
expandPath: func(s string) (string, error) {
s = strings.Replace(s, "~/", "", 1)
if filepath.IsAbs(s) {
return s, nil
}
return "/home/" + s, nil
},
devcontainers: []codersdk.WorkspaceAgentDevcontainer{
{
ID: devcontainerIDs[0],
WorkspaceFolder: "workspace1",
ConfigPath: "~/config1",
},
{
ID: devcontainerIDs[1],
WorkspaceFolder: "workspace2",
ConfigPath: "/config2",
},
},
scripts: []codersdk.WorkspaceAgentScript{
{ID: devcontainerIDs[0], RunOnStart: true},
{ID: devcontainerIDs[1], RunOnStart: true},
},
},
wantFilteredScripts: []codersdk.WorkspaceAgentScript{},
wantDevcontainerScripts: []codersdk.WorkspaceAgentScript{
{
ID: devcontainerIDs[0],
Script: "devcontainer up --log-format json --workspace-folder \"/home/workspace1\" --config \"/home/config1\"",
RunOnStart: false,
},
{
ID: devcontainerIDs[1],
Script: "devcontainer up --log-format json --workspace-folder \"/home/workspace2\" --config \"/config2\"",
RunOnStart: false,
},
},
skipOnWindowsDueToPathSeparator: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if tt.skipOnWindowsDueToPathSeparator && filepath.Separator == '\\' {
t.Skip("Skipping test on Windows due to path separator difference.")
}
logger := slogtest.Make(t, nil)
if tt.args.expandPath == nil {
tt.args.expandPath = func(s string) (string, error) {
return s, nil
}
}
gotFilteredScripts, gotDevcontainerScripts := agentcontainers.ExtractAndInitializeDevcontainerScripts(
agentcontainers.ExpandAllDevcontainerPaths(logger, tt.args.expandPath, tt.args.devcontainers),
tt.args.scripts,
)
if diff := cmp.Diff(tt.wantFilteredScripts, gotFilteredScripts, cmpopts.EquateEmpty()); diff != "" {
t.Errorf("ExtractAndInitializeDevcontainerScripts() gotFilteredScripts mismatch (-want +got):\n%s", diff)
}
// Preprocess the devcontainer scripts to remove scripting part.
for i := range gotDevcontainerScripts {
gotDevcontainerScripts[i].Script = textGrep("devcontainer up", gotDevcontainerScripts[i].Script)
require.NotEmpty(t, gotDevcontainerScripts[i].Script, "devcontainer up script not found")
}
if diff := cmp.Diff(tt.wantDevcontainerScripts, gotDevcontainerScripts); diff != "" {
t.Errorf("ExtractAndInitializeDevcontainerScripts() gotDevcontainerScripts mismatch (-want +got):\n%s", diff)
}
})
}
}
// textGrep returns matching lines from multiline string.
func textGrep(want, got string) (filtered string) {
var lines []string
for _, line := range strings.Split(got, "\n") {
if strings.Contains(line, want) {
lines = append(lines, line)
}
}
return strings.Join(lines, "\n")
}
+213
View File
@@ -0,0 +1,213 @@
package agentcontainers
import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"io"
"golang.org/x/xerrors"
"cdr.dev/slog"
"github.com/coder/coder/v2/agent/agentexec"
)
// DevcontainerCLI is an interface for the devcontainer CLI.
type DevcontainerCLI interface {
Up(ctx context.Context, workspaceFolder, configPath string, opts ...DevcontainerCLIUpOptions) (id string, err error)
}
// DevcontainerCLIUpOptions are options for the devcontainer CLI up
// command.
type DevcontainerCLIUpOptions func(*devcontainerCLIUpConfig)
// WithRemoveExistingContainer is an option to remove the existing
// container.
func WithRemoveExistingContainer() DevcontainerCLIUpOptions {
return func(o *devcontainerCLIUpConfig) {
o.removeExistingContainer = true
}
}
// WithOutput sets stdout and stderr writers for Up command logs.
func WithOutput(stdout, stderr io.Writer) DevcontainerCLIUpOptions {
return func(o *devcontainerCLIUpConfig) {
o.stdout = stdout
o.stderr = stderr
}
}
type devcontainerCLIUpConfig struct {
removeExistingContainer bool
stdout io.Writer
stderr io.Writer
}
func applyDevcontainerCLIUpOptions(opts []DevcontainerCLIUpOptions) devcontainerCLIUpConfig {
conf := devcontainerCLIUpConfig{
removeExistingContainer: false,
}
for _, opt := range opts {
if opt != nil {
opt(&conf)
}
}
return conf
}
type devcontainerCLI struct {
logger slog.Logger
execer agentexec.Execer
}
var _ DevcontainerCLI = &devcontainerCLI{}
func NewDevcontainerCLI(logger slog.Logger, execer agentexec.Execer) DevcontainerCLI {
return &devcontainerCLI{
execer: execer,
logger: logger,
}
}
func (d *devcontainerCLI) Up(ctx context.Context, workspaceFolder, configPath string, opts ...DevcontainerCLIUpOptions) (string, error) {
conf := applyDevcontainerCLIUpOptions(opts)
logger := d.logger.With(slog.F("workspace_folder", workspaceFolder), slog.F("config_path", configPath), slog.F("recreate", conf.removeExistingContainer))
args := []string{
"up",
"--log-format", "json",
"--workspace-folder", workspaceFolder,
}
if configPath != "" {
args = append(args, "--config", configPath)
}
if conf.removeExistingContainer {
args = append(args, "--remove-existing-container")
}
cmd := d.execer.CommandContext(ctx, "devcontainer", args...)
// Capture stdout for parsing and stream logs for both default and provided writers.
var stdoutBuf bytes.Buffer
stdoutWriters := []io.Writer{&stdoutBuf, &devcontainerCLILogWriter{ctx: ctx, logger: logger.With(slog.F("stdout", true))}}
if conf.stdout != nil {
stdoutWriters = append(stdoutWriters, conf.stdout)
}
cmd.Stdout = io.MultiWriter(stdoutWriters...)
// Stream stderr logs and provided writer if any.
stderrWriters := []io.Writer{&devcontainerCLILogWriter{ctx: ctx, logger: logger.With(slog.F("stderr", true))}}
if conf.stderr != nil {
stderrWriters = append(stderrWriters, conf.stderr)
}
cmd.Stderr = io.MultiWriter(stderrWriters...)
if err := cmd.Run(); err != nil {
if _, err2 := parseDevcontainerCLILastLine(ctx, logger, stdoutBuf.Bytes()); err2 != nil {
err = errors.Join(err, err2)
}
return "", err
}
result, err := parseDevcontainerCLILastLine(ctx, logger, stdoutBuf.Bytes())
if err != nil {
return "", err
}
return result.ContainerID, nil
}
// parseDevcontainerCLILastLine parses the last line of the devcontainer CLI output
// which is a JSON object.
func parseDevcontainerCLILastLine(ctx context.Context, logger slog.Logger, p []byte) (result devcontainerCLIResult, err error) {
s := bufio.NewScanner(bytes.NewReader(p))
var lastLine []byte
for s.Scan() {
b := s.Bytes()
if len(b) == 0 || b[0] != '{' {
continue
}
lastLine = b
}
if err = s.Err(); err != nil {
return result, err
}
if len(lastLine) == 0 || lastLine[0] != '{' {
logger.Error(ctx, "devcontainer result is not json", slog.F("result", string(lastLine)))
return result, xerrors.Errorf("devcontainer result is not json: %q", string(lastLine))
}
if err = json.Unmarshal(lastLine, &result); err != nil {
logger.Error(ctx, "parse devcontainer result failed", slog.Error(err), slog.F("result", string(lastLine)))
return result, err
}
return result, result.Err()
}
// devcontainerCLIResult is the result of the devcontainer CLI command.
// It is parsed from the last line of the devcontainer CLI stdout which
// is a JSON object.
type devcontainerCLIResult struct {
Outcome string `json:"outcome"` // "error", "success".
// The following fields are set if outcome is success.
ContainerID string `json:"containerId"`
RemoteUser string `json:"remoteUser"`
RemoteWorkspaceFolder string `json:"remoteWorkspaceFolder"`
// The following fields are set if outcome is error.
Message string `json:"message"`
Description string `json:"description"`
}
func (r devcontainerCLIResult) Err() error {
if r.Outcome == "success" {
return nil
}
return xerrors.Errorf("devcontainer up failed: %s (description: %s, message: %s)", r.Outcome, r.Description, r.Message)
}
// devcontainerCLIJSONLogLine is a log line from the devcontainer CLI.
type devcontainerCLIJSONLogLine struct {
Type string `json:"type"` // "progress", "raw", "start", "stop", "text", etc.
Level int `json:"level"` // 1, 2, 3.
Timestamp int `json:"timestamp"` // Unix timestamp in milliseconds.
Text string `json:"text"`
// More fields can be added here as needed.
}
// devcontainerCLILogWriter splits on newlines and logs each line
// separately.
type devcontainerCLILogWriter struct {
ctx context.Context
logger slog.Logger
}
func (l *devcontainerCLILogWriter) Write(p []byte) (n int, err error) {
s := bufio.NewScanner(bytes.NewReader(p))
for s.Scan() {
line := s.Bytes()
if len(line) == 0 {
continue
}
if line[0] != '{' {
l.logger.Debug(l.ctx, "@devcontainer/cli", slog.F("line", string(line)))
continue
}
var logLine devcontainerCLIJSONLogLine
if err := json.Unmarshal(line, &logLine); err != nil {
l.logger.Error(l.ctx, "parse devcontainer json log line failed", slog.Error(err), slog.F("line", string(line)))
continue
}
if logLine.Level >= 3 {
l.logger.Info(l.ctx, "@devcontainer/cli", slog.F("line", string(line)))
continue
}
l.logger.Debug(l.ctx, "@devcontainer/cli", slog.F("line", string(line)))
}
if err := s.Err(); err != nil {
l.logger.Error(l.ctx, "devcontainer log line scan failed", slog.Error(err))
}
return len(p), nil
}
@@ -0,0 +1,393 @@
package agentcontainers_test
import (
"bytes"
"context"
"errors"
"flag"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/agent/agentcontainers"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/pty"
"github.com/coder/coder/v2/testutil"
)
func TestDevcontainerCLI_ArgsAndParsing(t *testing.T) {
t.Parallel()
testExePath, err := os.Executable()
require.NoError(t, err, "get test executable path")
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
t.Run("Up", func(t *testing.T) {
t.Parallel()
tests := []struct {
name string
logFile string
workspace string
config string
opts []agentcontainers.DevcontainerCLIUpOptions
wantArgs string
wantError bool
}{
{
name: "success",
logFile: "up.log",
workspace: "/test/workspace",
wantArgs: "up --log-format json --workspace-folder /test/workspace",
wantError: false,
},
{
name: "success with config",
logFile: "up.log",
workspace: "/test/workspace",
config: "/test/config.json",
wantArgs: "up --log-format json --workspace-folder /test/workspace --config /test/config.json",
wantError: false,
},
{
name: "already exists",
logFile: "up-already-exists.log",
workspace: "/test/workspace",
wantArgs: "up --log-format json --workspace-folder /test/workspace",
wantError: false,
},
{
name: "docker error",
logFile: "up-error-docker.log",
workspace: "/test/workspace",
wantArgs: "up --log-format json --workspace-folder /test/workspace",
wantError: true,
},
{
name: "bad outcome",
logFile: "up-error-bad-outcome.log",
workspace: "/test/workspace",
wantArgs: "up --log-format json --workspace-folder /test/workspace",
wantError: true,
},
{
name: "does not exist",
logFile: "up-error-does-not-exist.log",
workspace: "/test/workspace",
wantArgs: "up --log-format json --workspace-folder /test/workspace",
wantError: true,
},
{
name: "with remove existing container",
logFile: "up.log",
workspace: "/test/workspace",
opts: []agentcontainers.DevcontainerCLIUpOptions{
agentcontainers.WithRemoveExistingContainer(),
},
wantArgs: "up --log-format json --workspace-folder /test/workspace --remove-existing-container",
wantError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t, testutil.WaitMedium)
testExecer := &testDevcontainerExecer{
testExePath: testExePath,
wantArgs: tt.wantArgs,
wantError: tt.wantError,
logFile: filepath.Join("testdata", "devcontainercli", "parse", tt.logFile),
}
dccli := agentcontainers.NewDevcontainerCLI(logger, testExecer)
containerID, err := dccli.Up(ctx, tt.workspace, tt.config, tt.opts...)
if tt.wantError {
assert.Error(t, err, "want error")
assert.Empty(t, containerID, "expected empty container ID")
} else {
assert.NoError(t, err, "want no error")
assert.NotEmpty(t, containerID, "expected non-empty container ID")
}
})
}
})
}
// TestDevcontainerCLI_WithOutput tests that WithOutput captures CLI
// logs to provided writers.
func TestDevcontainerCLI_WithOutput(t *testing.T) {
t.Parallel()
// Prepare test executable and logger.
testExePath, err := os.Executable()
require.NoError(t, err, "get test executable path")
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
ctx := testutil.Context(t, testutil.WaitMedium)
// Buffers to capture stdout and stderr.
outBuf := &bytes.Buffer{}
errBuf := &bytes.Buffer{}
// Simulate CLI execution with a standard up.log file.
wantArgs := "up --log-format json --workspace-folder /test/workspace"
testExecer := &testDevcontainerExecer{
testExePath: testExePath,
wantArgs: wantArgs,
wantError: false,
logFile: filepath.Join("testdata", "devcontainercli", "parse", "up.log"),
}
dccli := agentcontainers.NewDevcontainerCLI(logger, testExecer)
// Call Up with WithOutput to capture CLI logs.
containerID, err := dccli.Up(ctx, "/test/workspace", "", agentcontainers.WithOutput(outBuf, errBuf))
require.NoError(t, err, "Up should succeed")
require.NotEmpty(t, containerID, "expected non-empty container ID")
// Read expected log content.
expLog, err := os.ReadFile(filepath.Join("testdata", "devcontainercli", "parse", "up.log"))
require.NoError(t, err, "reading expected log file")
// Verify stdout buffer contains the CLI logs and stderr is empty.
assert.Equal(t, string(expLog), outBuf.String(), "stdout buffer should match CLI logs")
assert.Empty(t, errBuf.String(), "stderr buffer should be empty on success")
}
// testDevcontainerExecer implements the agentexec.Execer interface for testing.
type testDevcontainerExecer struct {
testExePath string
wantArgs string
wantError bool
logFile string
}
// CommandContext returns a test binary command that simulates devcontainer responses.
func (e *testDevcontainerExecer) CommandContext(ctx context.Context, name string, args ...string) *exec.Cmd {
// Only handle "devcontainer" commands.
if name != "devcontainer" {
// For non-devcontainer commands, use a standard execer.
return agentexec.DefaultExecer.CommandContext(ctx, name, args...)
}
// Create a command that runs the test binary with special flags
// that tell it to simulate a devcontainer command.
testArgs := []string{
"-test.run=TestDevcontainerHelperProcess",
"--",
name,
}
testArgs = append(testArgs, args...)
//nolint:gosec // This is a test binary, so we don't need to worry about command injection.
cmd := exec.CommandContext(ctx, e.testExePath, testArgs...)
// Set this environment variable so the child process knows it's the helper.
cmd.Env = append(os.Environ(),
"TEST_DEVCONTAINER_WANT_HELPER_PROCESS=1",
"TEST_DEVCONTAINER_WANT_ARGS="+e.wantArgs,
"TEST_DEVCONTAINER_WANT_ERROR="+fmt.Sprintf("%v", e.wantError),
"TEST_DEVCONTAINER_LOG_FILE="+e.logFile,
)
return cmd
}
// PTYCommandContext returns a PTY command.
func (*testDevcontainerExecer) PTYCommandContext(_ context.Context, name string, args ...string) *pty.Cmd {
// This method shouldn't be called for our devcontainer tests.
panic("PTYCommandContext not expected in devcontainer tests")
}
// This is a special test helper that is executed as a subprocess.
// It simulates the behavior of the devcontainer CLI.
//
//nolint:revive,paralleltest // This is a test helper function.
func TestDevcontainerHelperProcess(t *testing.T) {
// If not called by the test as a helper process, do nothing.
if os.Getenv("TEST_DEVCONTAINER_WANT_HELPER_PROCESS") != "1" {
return
}
helperArgs := flag.Args()
if len(helperArgs) < 1 {
fmt.Fprintf(os.Stderr, "No command\n")
os.Exit(2)
}
if helperArgs[0] != "devcontainer" {
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", helperArgs[0])
os.Exit(2)
}
// Verify arguments against expected arguments and skip
// "devcontainer", it's not included in the input args.
wantArgs := os.Getenv("TEST_DEVCONTAINER_WANT_ARGS")
gotArgs := strings.Join(helperArgs[1:], " ")
if gotArgs != wantArgs {
fmt.Fprintf(os.Stderr, "Arguments don't match.\nWant: %q\nGot: %q\n",
wantArgs, gotArgs)
os.Exit(2)
}
logFilePath := os.Getenv("TEST_DEVCONTAINER_LOG_FILE")
output, err := os.ReadFile(logFilePath)
if err != nil {
fmt.Fprintf(os.Stderr, "Reading log file %s failed: %v\n", logFilePath, err)
os.Exit(2)
}
_, _ = io.Copy(os.Stdout, bytes.NewReader(output))
if os.Getenv("TEST_DEVCONTAINER_WANT_ERROR") == "true" {
os.Exit(1)
}
os.Exit(0)
}
// TestDockerDevcontainerCLI tests the DevcontainerCLI component with real Docker containers.
// This test verifies that containers can be created and recreated using the actual
// devcontainer CLI and Docker. It is skipped by default and can be run with:
//
// CODER_TEST_USE_DOCKER=1 go test ./agent/agentcontainers -run TestDockerDevcontainerCLI
//
// The test requires Docker to be installed and running.
func TestDockerDevcontainerCLI(t *testing.T) {
t.Parallel()
if os.Getenv("CODER_TEST_USE_DOCKER") != "1" {
t.Skip("skipping Docker test; set CODER_TEST_USE_DOCKER=1 to run")
}
if _, err := exec.LookPath("devcontainer"); err != nil {
t.Fatal("this test requires the devcontainer CLI: npm install -g @devcontainers/cli")
}
// Connect to Docker.
pool, err := dockertest.NewPool("")
require.NoError(t, err, "connect to Docker")
t.Run("ContainerLifecycle", func(t *testing.T) {
t.Parallel()
// Set up workspace directory with a devcontainer configuration.
workspaceFolder := t.TempDir()
configPath := setupDevcontainerWorkspace(t, workspaceFolder)
// Use a long timeout because container operations are slow.
ctx := testutil.Context(t, testutil.WaitLong)
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
// Create the devcontainer CLI under test.
dccli := agentcontainers.NewDevcontainerCLI(logger, agentexec.DefaultExecer)
// Create a container.
firstID, err := dccli.Up(ctx, workspaceFolder, configPath)
require.NoError(t, err, "create container")
require.NotEmpty(t, firstID, "container ID should not be empty")
defer removeDevcontainerByID(t, pool, firstID)
// Verify container exists.
firstContainer, found := findDevcontainerByID(t, pool, firstID)
require.True(t, found, "container should exist")
// Remember the container creation time.
firstCreated := firstContainer.Created
// Recreate the container.
secondID, err := dccli.Up(ctx, workspaceFolder, configPath, agentcontainers.WithRemoveExistingContainer())
require.NoError(t, err, "recreate container")
require.NotEmpty(t, secondID, "recreated container ID should not be empty")
defer removeDevcontainerByID(t, pool, secondID)
// Verify the new container exists and is different.
secondContainer, found := findDevcontainerByID(t, pool, secondID)
require.True(t, found, "recreated container should exist")
// Verify it's a different container by checking creation time.
secondCreated := secondContainer.Created
assert.NotEqual(t, firstCreated, secondCreated, "recreated container should have different creation time")
// Verify the first container is removed by the recreation.
_, found = findDevcontainerByID(t, pool, firstID)
assert.False(t, found, "first container should be removed")
})
}
// setupDevcontainerWorkspace prepares a test environment with a minimal
// devcontainer.json configuration and returns the path to the config file.
func setupDevcontainerWorkspace(t *testing.T, workspaceFolder string) string {
t.Helper()
// Create the devcontainer directory structure.
devcontainerDir := filepath.Join(workspaceFolder, ".devcontainer")
err := os.MkdirAll(devcontainerDir, 0o755)
require.NoError(t, err, "create .devcontainer directory")
// Write a minimal configuration with test labels for identification.
configPath := filepath.Join(devcontainerDir, "devcontainer.json")
content := `{
"image": "alpine:latest",
"containerEnv": {
"TEST_CONTAINER": "true"
},
"runArgs": ["--label", "com.coder.test=devcontainercli"]
}`
err = os.WriteFile(configPath, []byte(content), 0o600)
require.NoError(t, err, "create devcontainer.json file")
return configPath
}
// findDevcontainerByID locates a container by its ID and verifies it has our
// test label. Returns the container and whether it was found.
func findDevcontainerByID(t *testing.T, pool *dockertest.Pool, id string) (*docker.Container, bool) {
t.Helper()
container, err := pool.Client.InspectContainer(id)
if err != nil {
t.Logf("Inspect container failed: %v", err)
return nil, false
}
require.Equal(t, "devcontainercli", container.Config.Labels["com.coder.test"], "sanity check failed: container should have the test label")
return container, true
}
// removeDevcontainerByID safely cleans up a test container by ID, verifying
// it has our test label before removal to prevent accidental deletion.
func removeDevcontainerByID(t *testing.T, pool *dockertest.Pool, id string) {
t.Helper()
errNoSuchContainer := &docker.NoSuchContainer{}
// Check if the container has the expected label.
container, err := pool.Client.InspectContainer(id)
if err != nil {
if errors.As(err, &errNoSuchContainer) {
t.Logf("Container %s not found, skipping removal", id)
return
}
require.NoError(t, err, "inspect container")
}
require.Equal(t, "devcontainercli", container.Config.Labels["com.coder.test"], "sanity check failed: container should have the test label")
t.Logf("Removing container with ID: %s", id)
err = pool.Client.RemoveContainer(docker.RemoveContainerOptions{
ID: container.ID,
Force: true,
RemoveVolumes: true,
})
if err != nil && !errors.As(err, &errNoSuchContainer) {
assert.NoError(t, err, "remove container failed")
}
}
@@ -0,0 +1,221 @@
[
{
"Id": "fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a",
"Created": "2025-03-11T17:58:43.522505027Z",
"Path": "sleep",
"Args": [
"infinity"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 644296,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:58:43.569966691Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a/hostname",
"HostsPath": "/var/lib/docker/containers/fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a/hosts",
"LogPath": "/var/lib/docker/containers/fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a/fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a-json.log",
"Name": "/silly_beaver",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/tmp/test/a:/var/coder/a:ro",
"/tmp/test/b:/var/coder/b"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "fdc75ebefdc0243c0fce959e7685931691ac7aede278664a0e2c23af8a1e8d6a",
"LowerDir": "/var/lib/docker/overlay2/c1519be93f8e138757310f6ed8c3946a524cdae2580ad8579913d19c3fe9ffd2-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/c1519be93f8e138757310f6ed8c3946a524cdae2580ad8579913d19c3fe9ffd2/merged",
"UpperDir": "/var/lib/docker/overlay2/c1519be93f8e138757310f6ed8c3946a524cdae2580ad8579913d19c3fe9ffd2/diff",
"WorkDir": "/var/lib/docker/overlay2/c1519be93f8e138757310f6ed8c3946a524cdae2580ad8579913d19c3fe9ffd2/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/test/a",
"Destination": "/var/coder/a",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/tmp/test/b",
"Destination": "/var/coder/b",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "fdc75ebefdc0",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"infinity"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "46f98b32002740b63709e3ebf87c78efe652adfaa8753b85d79b814f26d88107",
"SandboxKey": "/var/run/docker/netns/46f98b320027",
"Ports": {},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "356e429f15e354dd23250c7a3516aecf1a2afe9d58ea1dc2e97e33a75ac346a8",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "22:2c:26:d9:da:83",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "22:2c:26:d9:da:83",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "356e429f15e354dd23250c7a3516aecf1a2afe9d58ea1dc2e97e33a75ac346a8",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,222 @@
[
{
"Id": "3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea",
"Created": "2025-03-11T17:57:08.862545133Z",
"Path": "sleep",
"Args": [
"infinity"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 640137,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:57:08.909898821Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea/hostname",
"HostsPath": "/var/lib/docker/containers/3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea/hosts",
"LogPath": "/var/lib/docker/containers/3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea/3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea-json.log",
"Name": "/boring_ellis",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {
"23456/tcp": [
{
"HostIp": "",
"HostPort": "12345"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "3090de8b72b1224758a94a11b827c82ba2b09c45524f1263dc4a2d83e19625ea",
"LowerDir": "/var/lib/docker/overlay2/e9f2dda207bde1f4b277f973457107d62cff259881901adcd9bcccfea9a92231-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/e9f2dda207bde1f4b277f973457107d62cff259881901adcd9bcccfea9a92231/merged",
"UpperDir": "/var/lib/docker/overlay2/e9f2dda207bde1f4b277f973457107d62cff259881901adcd9bcccfea9a92231/diff",
"WorkDir": "/var/lib/docker/overlay2/e9f2dda207bde1f4b277f973457107d62cff259881901adcd9bcccfea9a92231/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "3090de8b72b1",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"23456/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"infinity"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "ebcd8b749b4c719f90d80605c352b7aa508e4c61d9dcd2919654f18f17eb2840",
"SandboxKey": "/var/run/docker/netns/ebcd8b749b4c",
"Ports": {
"23456/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "12345"
},
{
"HostIp": "::",
"HostPort": "12345"
}
]
},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "465824b3cc6bdd2b307e9c614815fd458b1baac113dee889c3620f0cac3183fa",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "52:b6:f6:7b:4b:5b",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "52:b6:f6:7b:4b:5b",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "465824b3cc6bdd2b307e9c614815fd458b1baac113dee889c3620f0cac3183fa",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,204 @@
[
{
"Id": "bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f",
"Created": "2025-03-11T20:03:28.071706536Z",
"Path": "sleep",
"Args": [
"infinity"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 913862,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T20:03:28.123599065Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f/hostname",
"HostsPath": "/var/lib/docker/containers/bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f/hosts",
"LogPath": "/var/lib/docker/containers/bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f/bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f-json.log",
"Name": "/fervent_bardeen",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "bd8818e670230fc6f36145b21cf8d6d35580355662aa4d9fe5ae1b188a4c905f",
"LowerDir": "/var/lib/docker/overlay2/55fc45976c381040c7d261c198333e6331889c51afe1500e2e7837c189a1b794-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/55fc45976c381040c7d261c198333e6331889c51afe1500e2e7837c189a1b794/merged",
"UpperDir": "/var/lib/docker/overlay2/55fc45976c381040c7d261c198333e6331889c51afe1500e2e7837c189a1b794/diff",
"WorkDir": "/var/lib/docker/overlay2/55fc45976c381040c7d261c198333e6331889c51afe1500e2e7837c189a1b794/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "bd8818e67023",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"infinity"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": null,
"Labels": {
"baz": "zap",
"foo": "bar"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "24faa8b9aaa58c651deca0d85a3f7bcc6c3e5e1a24b6369211f736d6e82f8ab0",
"SandboxKey": "/var/run/docker/netns/24faa8b9aaa5",
"Ports": {},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "c686f97d772d75c8ceed9285e06c1f671b71d4775d5513f93f26358c0f0b4671",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "96:88:4e:3b:11:44",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "96:88:4e:3b:11:44",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "c686f97d772d75c8ceed9285e06c1f671b71d4775d5513f93f26358c0f0b4671",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,222 @@
[
{
"Id": "4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2",
"Created": "2025-03-11T17:56:34.842164541Z",
"Path": "sleep",
"Args": [
"infinity"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 638449,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:56:34.894488648Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2/hostname",
"HostsPath": "/var/lib/docker/containers/4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2/hosts",
"LogPath": "/var/lib/docker/containers/4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2/4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2-json.log",
"Name": "/modest_varahamihira",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {
"12345/tcp": [
{
"HostIp": "",
"HostPort": "12345"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "4eac5ce199d27b2329d0ff0ce1a6fc595612ced48eba3669aadb6c57ebef3fa2",
"LowerDir": "/var/lib/docker/overlay2/35deac62dd3f610275aaf145d091aaa487f73a3c99de5a90df8ab871c969bc0b-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/35deac62dd3f610275aaf145d091aaa487f73a3c99de5a90df8ab871c969bc0b/merged",
"UpperDir": "/var/lib/docker/overlay2/35deac62dd3f610275aaf145d091aaa487f73a3c99de5a90df8ab871c969bc0b/diff",
"WorkDir": "/var/lib/docker/overlay2/35deac62dd3f610275aaf145d091aaa487f73a3c99de5a90df8ab871c969bc0b/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "4eac5ce199d2",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"12345/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"infinity"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "5e966e97ba02013054e0ef15ef87f8629f359ad882fad4c57b33c768ad9b90dc",
"SandboxKey": "/var/run/docker/netns/5e966e97ba02",
"Ports": {
"12345/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "12345"
},
{
"HostIp": "::",
"HostPort": "12345"
}
]
},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "f9e1896fc0ef48f3ea9aff3b4e98bc4291ba246412178331345f7b0745cccba9",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "be:a6:89:39:7e:b0",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "be:a6:89:39:7e:b0",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "f9e1896fc0ef48f3ea9aff3b4e98bc4291ba246412178331345f7b0745cccba9",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,51 @@
[
{
"Id": "a",
"Created": "2025-03-11T17:56:34.842164541Z",
"State": {
"Running": true,
"ExitCode": 0,
"Error": ""
},
"Name": "/a",
"Mounts": [],
"Config": {
"Image": "debian:bookworm",
"Labels": {}
},
"NetworkSettings": {
"Ports": {
"8001/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "8000"
}
]
}
}
},
{
"Id": "b",
"Created": "2025-03-11T17:56:34.842164541Z",
"State": {
"Running": true,
"ExitCode": 0,
"Error": ""
},
"Name": "/b",
"Config": {
"Image": "debian:bookworm",
"Labels": {}
},
"NetworkSettings": {
"Ports": {
"8001/tcp": [
{
"HostIp": "::",
"HostPort": "8000"
}
]
}
}
}
]
@@ -0,0 +1,201 @@
[
{
"Id": "6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286",
"Created": "2025-03-11T17:55:58.091280203Z",
"Path": "sleep",
"Args": [
"infinity"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 636855,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:55:58.142417459Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286/hostname",
"HostsPath": "/var/lib/docker/containers/6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286/hosts",
"LogPath": "/var/lib/docker/containers/6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286/6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286-json.log",
"Name": "/eloquent_kowalevski",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "6b539b8c60f5230b8b0fde2502cd2332d31c0d526a3e6eb6eef1cc39439b3286",
"LowerDir": "/var/lib/docker/overlay2/4093560d7757c088e24060e5ff6f32807d8e733008c42b8af7057fe4fe6f56ba-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/4093560d7757c088e24060e5ff6f32807d8e733008c42b8af7057fe4fe6f56ba/merged",
"UpperDir": "/var/lib/docker/overlay2/4093560d7757c088e24060e5ff6f32807d8e733008c42b8af7057fe4fe6f56ba/diff",
"WorkDir": "/var/lib/docker/overlay2/4093560d7757c088e24060e5ff6f32807d8e733008c42b8af7057fe4fe6f56ba/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "6b539b8c60f5",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"infinity"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "08f2f3218a6d63ae149ab77672659d96b88bca350e85889240579ecb427e8011",
"SandboxKey": "/var/run/docker/netns/08f2f3218a6d",
"Ports": {},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "f83bd20711df6d6ff7e2f44f4b5799636cd94596ae25ffe507a70f424073532c",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "f6:84:26:7a:10:5b",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "f6:84:26:7a:10:5b",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "f83bd20711df6d6ff7e2f44f4b5799636cd94596ae25ffe507a70f424073532c",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,214 @@
[
{
"Id": "b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e",
"Created": "2025-03-11T17:59:42.039484134Z",
"Path": "sleep",
"Args": [
"infinity"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 646777,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:59:42.081315917Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e/hostname",
"HostsPath": "/var/lib/docker/containers/b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e/hosts",
"LogPath": "/var/lib/docker/containers/b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e/b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e-json.log",
"Name": "/upbeat_carver",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"testvol:/testvol"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "b3688d98c007f53402a55e46d803f2f3ba9181d8e3f71a2eb19b392cf0377b4e",
"LowerDir": "/var/lib/docker/overlay2/d71790d2558bf17d7535451094e332780638a4e92697c021176f3447fc4c50f4-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/d71790d2558bf17d7535451094e332780638a4e92697c021176f3447fc4c50f4/merged",
"UpperDir": "/var/lib/docker/overlay2/d71790d2558bf17d7535451094e332780638a4e92697c021176f3447fc4c50f4/diff",
"WorkDir": "/var/lib/docker/overlay2/d71790d2558bf17d7535451094e332780638a4e92697c021176f3447fc4c50f4/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "testvol",
"Source": "/var/lib/docker/volumes/testvol/_data",
"Destination": "/testvol",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "b3688d98c007",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"infinity"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "e617ea865af5690d06c25df1c9a0154b98b4da6bbb9e0afae3b80ad29902538a",
"SandboxKey": "/var/run/docker/netns/e617ea865af5",
"Ports": {},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "1a7bb5bbe4af0674476c95c5d1c913348bc82a5f01fd1c1b394afc44d1cf5a49",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "4a:d8:a5:47:1c:54",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "4a:d8:a5:47:1c:54",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "1a7bb5bbe4af0674476c95c5d1c913348bc82a5f01fd1c1b394afc44d1cf5a49",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,230 @@
[
{
"Id": "52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3",
"Created": "2025-03-11T17:02:42.613747761Z",
"Path": "/bin/sh",
"Args": [
"-c",
"echo Container started\ntrap \"exit 0\" 15\n\nexec \"$@\"\nwhile sleep 1 & wait $!; do :; done",
"-"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 526198,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:02:42.658905789Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3/hostname",
"HostsPath": "/var/lib/docker/containers/52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3/hosts",
"LogPath": "/var/lib/docker/containers/52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3/52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3-json.log",
"Name": "/suspicious_margulis",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {
"8080/tcp": [
{
"HostIp": "",
"HostPort": ""
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "52d23691f4b954d083f117358ea763e20f69af584e1c08f479c5752629ee0be3",
"LowerDir": "/var/lib/docker/overlay2/e204eab11c98b3cacc18d5a0e7290c0c286a96d918c31e5c2fed4124132eec4f-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/e204eab11c98b3cacc18d5a0e7290c0c286a96d918c31e5c2fed4124132eec4f/merged",
"UpperDir": "/var/lib/docker/overlay2/e204eab11c98b3cacc18d5a0e7290c0c286a96d918c31e5c2fed4124132eec4f/diff",
"WorkDir": "/var/lib/docker/overlay2/e204eab11c98b3cacc18d5a0e7290c0c286a96d918c31e5c2fed4124132eec4f/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "52d23691f4b9",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"ExposedPorts": {
"8080/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"-c",
"echo Container started\ntrap \"exit 0\" 15\n\nexec \"$@\"\nwhile sleep 1 & wait $!; do :; done",
"-"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/sh"
],
"OnBuild": null,
"Labels": {
"devcontainer.config_file": "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_appport.json",
"devcontainer.metadata": "[]"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "e4fa65f769e331c72e27f43af2d65073efca638fd413b7c57f763ee9ebf69020",
"SandboxKey": "/var/run/docker/netns/e4fa65f769e3",
"Ports": {
"8080/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "32768"
},
{
"HostIp": "::",
"HostPort": "32768"
}
]
},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "14531bbbb26052456a4509e6d23753de45096ca8355ac11684c631d1656248ad",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "36:88:48:04:4e:b4",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "36:88:48:04:4e:b4",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "14531bbbb26052456a4509e6d23753de45096ca8355ac11684c631d1656248ad",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,209 @@
[
{
"Id": "4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067",
"Created": "2025-03-11T17:03:55.022053072Z",
"Path": "/bin/sh",
"Args": [
"-c",
"echo Container started\ntrap \"exit 0\" 15\n\nexec \"$@\"\nwhile sleep 1 & wait $!; do :; done",
"-"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 529591,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:03:55.064323762Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067/hostname",
"HostsPath": "/var/lib/docker/containers/4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067/hosts",
"LogPath": "/var/lib/docker/containers/4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067/4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067-json.log",
"Name": "/serene_khayyam",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "4a16af2293fb75dc827a6949a3905dd57ea28cc008823218ce24fab1cb66c067",
"LowerDir": "/var/lib/docker/overlay2/1974a49367024c771135c80dd6b62ba46cdebfa866e67a5408426c88a30bac3e-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/1974a49367024c771135c80dd6b62ba46cdebfa866e67a5408426c88a30bac3e/merged",
"UpperDir": "/var/lib/docker/overlay2/1974a49367024c771135c80dd6b62ba46cdebfa866e67a5408426c88a30bac3e/diff",
"WorkDir": "/var/lib/docker/overlay2/1974a49367024c771135c80dd6b62ba46cdebfa866e67a5408426c88a30bac3e/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "4a16af2293fb",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"-c",
"echo Container started\ntrap \"exit 0\" 15\n\nexec \"$@\"\nwhile sleep 1 & wait $!; do :; done",
"-"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/sh"
],
"OnBuild": null,
"Labels": {
"devcontainer.config_file": "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_forwardport.json",
"devcontainer.metadata": "[]"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "e1c3bddb359d16c45d6d132561b83205af7809b01ed5cb985a8cb1b416b2ddd5",
"SandboxKey": "/var/run/docker/netns/e1c3bddb359d",
"Ports": {},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "2899f34f5f8b928619952dc32566d82bc121b033453f72e5de4a743feabc423b",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "3e:94:61:83:1f:58",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "3e:94:61:83:1f:58",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "2899f34f5f8b928619952dc32566d82bc121b033453f72e5de4a743feabc423b",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,209 @@
[
{
"Id": "0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed",
"Created": "2025-03-11T17:01:05.751972661Z",
"Path": "/bin/sh",
"Args": [
"-c",
"echo Container started\ntrap \"exit 0\" 15\n\nexec \"$@\"\nwhile sleep 1 & wait $!; do :; done",
"-"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 521929,
"ExitCode": 0,
"Error": "",
"StartedAt": "2025-03-11T17:01:06.002539252Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:d4ccddb816ba27eaae22ef3d56175d53f47998e2acb99df1ae0e5b426b28a076",
"ResolvConfPath": "/var/lib/docker/containers/0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed/hostname",
"HostsPath": "/var/lib/docker/containers/0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed/hosts",
"LogPath": "/var/lib/docker/containers/0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed/0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed-json.log",
"Name": "/optimistic_hopper",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
108,
176
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 10,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": [],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"ID": "0b2a9fcf5727d9562943ce47d445019f4520e37a2aa7c6d9346d01af4f4f9aed",
"LowerDir": "/var/lib/docker/overlay2/b698fd9f03f25014d4936cdc64ed258342fe685f0dfd8813ed6928dd6de75219-init/diff:/var/lib/docker/overlay2/4b4c37dfbdc0dc01b68d4fb1ddb86109398a2d73555439b874dbd23b87cd5c4b/diff",
"MergedDir": "/var/lib/docker/overlay2/b698fd9f03f25014d4936cdc64ed258342fe685f0dfd8813ed6928dd6de75219/merged",
"UpperDir": "/var/lib/docker/overlay2/b698fd9f03f25014d4936cdc64ed258342fe685f0dfd8813ed6928dd6de75219/diff",
"WorkDir": "/var/lib/docker/overlay2/b698fd9f03f25014d4936cdc64ed258342fe685f0dfd8813ed6928dd6de75219/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "0b2a9fcf5727",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"-c",
"echo Container started\ntrap \"exit 0\" 15\n\nexec \"$@\"\nwhile sleep 1 & wait $!; do :; done",
"-"
],
"Image": "debian:bookworm",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/bin/sh"
],
"OnBuild": null,
"Labels": {
"devcontainer.config_file": "/home/coder/src/coder/coder/agent/agentcontainers/testdata/devcontainer_simple.json",
"devcontainer.metadata": "[]"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "25a29a57c1330e0d0d2342af6e3291ffd3e812aca1a6e3f6a1630e74b73d0fc6",
"SandboxKey": "/var/run/docker/netns/25a29a57c133",
"Ports": {},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "5c5ebda526d8fca90e841886ea81b77d7cc97fed56980c2aa89d275b84af7df2",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "32:b6:d9:ab:c3:61",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"MacAddress": "32:b6:d9:ab:c3:61",
"DriverOpts": null,
"GwPriority": 0,
"NetworkID": "c4dd768ab4945e41ad23fe3907c960dac811141592a861cc40038df7086a1ce1",
"EndpointID": "5c5ebda526d8fca90e841886ea81b77d7cc97fed56980c2aa89d275b84af7df2",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DNSNames": null
}
}
}
}
]
@@ -0,0 +1,68 @@
{"type":"text","level":3,"timestamp":1744102135254,"text":"@devcontainers/cli 0.75.0. Node.js v23.9.0. darwin 24.4.0 arm64."}
{"type":"start","level":2,"timestamp":1744102135254,"text":"Run: docker buildx version"}
{"type":"stop","level":2,"timestamp":1744102135300,"text":"Run: docker buildx version","startTimestamp":1744102135254}
{"type":"text","level":2,"timestamp":1744102135300,"text":"github.com/docker/buildx v0.21.2 1360a9e8d25a2c3d03c2776d53ae62e6ff0a843d\r\n"}
{"type":"text","level":2,"timestamp":1744102135300,"text":"\u001b[1m\u001b[31m\u001b[39m\u001b[22m\r\n"}
{"type":"start","level":2,"timestamp":1744102135300,"text":"Run: docker -v"}
{"type":"stop","level":2,"timestamp":1744102135309,"text":"Run: docker -v","startTimestamp":1744102135300}
{"type":"start","level":2,"timestamp":1744102135309,"text":"Resolving Remote"}
{"type":"start","level":2,"timestamp":1744102135311,"text":"Run: git rev-parse --show-cdup"}
{"type":"stop","level":2,"timestamp":1744102135316,"text":"Run: git rev-parse --show-cdup","startTimestamp":1744102135311}
{"type":"start","level":2,"timestamp":1744102135316,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/code/devcontainers-template-starter --filter label=devcontainer.config_file=/code/devcontainers-template-starter/.devcontainer/devcontainer.json"}
{"type":"stop","level":2,"timestamp":1744102135333,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/code/devcontainers-template-starter --filter label=devcontainer.config_file=/code/devcontainers-template-starter/.devcontainer/devcontainer.json","startTimestamp":1744102135316}
{"type":"start","level":2,"timestamp":1744102135333,"text":"Run: docker inspect --type container 4f22413fe134"}
{"type":"stop","level":2,"timestamp":1744102135347,"text":"Run: docker inspect --type container 4f22413fe134","startTimestamp":1744102135333}
{"type":"start","level":2,"timestamp":1744102135348,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/code/devcontainers-template-starter --filter label=devcontainer.config_file=/code/devcontainers-template-starter/.devcontainer/devcontainer.json"}
{"type":"stop","level":2,"timestamp":1744102135364,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/code/devcontainers-template-starter --filter label=devcontainer.config_file=/code/devcontainers-template-starter/.devcontainer/devcontainer.json","startTimestamp":1744102135348}
{"type":"start","level":2,"timestamp":1744102135364,"text":"Run: docker inspect --type container 4f22413fe134"}
{"type":"stop","level":2,"timestamp":1744102135378,"text":"Run: docker inspect --type container 4f22413fe134","startTimestamp":1744102135364}
{"type":"start","level":2,"timestamp":1744102135379,"text":"Inspecting container"}
{"type":"start","level":2,"timestamp":1744102135379,"text":"Run: docker inspect --type container 4f22413fe13472200500a66ca057df5aafba6b45743afd499c3f26fc886eb236"}
{"type":"stop","level":2,"timestamp":1744102135393,"text":"Run: docker inspect --type container 4f22413fe13472200500a66ca057df5aafba6b45743afd499c3f26fc886eb236","startTimestamp":1744102135379}
{"type":"stop","level":2,"timestamp":1744102135393,"text":"Inspecting container","startTimestamp":1744102135379}
{"type":"start","level":2,"timestamp":1744102135393,"text":"Run in container: /bin/sh"}
{"type":"start","level":2,"timestamp":1744102135394,"text":"Run in container: uname -m"}
{"type":"text","level":2,"timestamp":1744102135428,"text":"aarch64\n"}
{"type":"text","level":2,"timestamp":1744102135428,"text":""}
{"type":"stop","level":2,"timestamp":1744102135428,"text":"Run in container: uname -m","startTimestamp":1744102135394}
{"type":"start","level":2,"timestamp":1744102135428,"text":"Run in container: (cat /etc/os-release || cat /usr/lib/os-release) 2>/dev/null"}
{"type":"text","level":2,"timestamp":1744102135428,"text":"PRETTY_NAME=\"Debian GNU/Linux 11 (bullseye)\"\nNAME=\"Debian GNU/Linux\"\nVERSION_ID=\"11\"\nVERSION=\"11 (bullseye)\"\nVERSION_CODENAME=bullseye\nID=debian\nHOME_URL=\"https://www.debian.org/\"\nSUPPORT_URL=\"https://www.debian.org/support\"\nBUG_REPORT_URL=\"https://bugs.debian.org/\"\n"}
{"type":"text","level":2,"timestamp":1744102135428,"text":""}
{"type":"stop","level":2,"timestamp":1744102135428,"text":"Run in container: (cat /etc/os-release || cat /usr/lib/os-release) 2>/dev/null","startTimestamp":1744102135428}
{"type":"start","level":2,"timestamp":1744102135429,"text":"Run in container: (command -v getent >/dev/null 2>&1 && getent passwd 'node' || grep -E '^node|^[^:]*:[^:]*:node:' /etc/passwd || true)"}
{"type":"stop","level":2,"timestamp":1744102135429,"text":"Run in container: (command -v getent >/dev/null 2>&1 && getent passwd 'node' || grep -E '^node|^[^:]*:[^:]*:node:' /etc/passwd || true)","startTimestamp":1744102135429}
{"type":"start","level":2,"timestamp":1744102135430,"text":"Run in container: test -f '/var/devcontainer/.patchEtcEnvironmentMarker'"}
{"type":"text","level":2,"timestamp":1744102135430,"text":""}
{"type":"text","level":2,"timestamp":1744102135430,"text":""}
{"type":"stop","level":2,"timestamp":1744102135430,"text":"Run in container: test -f '/var/devcontainer/.patchEtcEnvironmentMarker'","startTimestamp":1744102135430}
{"type":"start","level":2,"timestamp":1744102135430,"text":"Run in container: test -f '/var/devcontainer/.patchEtcProfileMarker'"}
{"type":"text","level":2,"timestamp":1744102135430,"text":""}
{"type":"text","level":2,"timestamp":1744102135430,"text":""}
{"type":"stop","level":2,"timestamp":1744102135430,"text":"Run in container: test -f '/var/devcontainer/.patchEtcProfileMarker'","startTimestamp":1744102135430}
{"type":"text","level":2,"timestamp":1744102135431,"text":"userEnvProbe: loginInteractiveShell (default)"}
{"type":"text","level":1,"timestamp":1744102135431,"text":"LifecycleCommandExecutionMap: {\n \"onCreateCommand\": [],\n \"updateContentCommand\": [],\n \"postCreateCommand\": [\n {\n \"origin\": \"devcontainer.json\",\n \"command\": \"npm install -g @devcontainers/cli\"\n }\n ],\n \"postStartCommand\": [],\n \"postAttachCommand\": [],\n \"initializeCommand\": []\n}"}
{"type":"text","level":2,"timestamp":1744102135431,"text":"userEnvProbe: not found in cache"}
{"type":"text","level":2,"timestamp":1744102135431,"text":"userEnvProbe shell: /bin/bash"}
{"type":"start","level":2,"timestamp":1744102135431,"text":"Run in container: /bin/bash -lic echo -n 5805f204-cd2b-4911-8a88-96de28d5deb7; cat /proc/self/environ; echo -n 5805f204-cd2b-4911-8a88-96de28d5deb7"}
{"type":"start","level":2,"timestamp":1744102135431,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.onCreateCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-07T09:21:41.201379807Z}\" != '2025-04-07T09:21:41.201379807Z' ] && echo '2025-04-07T09:21:41.201379807Z' > '/home/node/.devcontainer/.onCreateCommandMarker'"}
{"type":"text","level":2,"timestamp":1744102135432,"text":""}
{"type":"text","level":2,"timestamp":1744102135432,"text":""}
{"type":"text","level":2,"timestamp":1744102135432,"text":"Exit code 1"}
{"type":"stop","level":2,"timestamp":1744102135432,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.onCreateCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-07T09:21:41.201379807Z}\" != '2025-04-07T09:21:41.201379807Z' ] && echo '2025-04-07T09:21:41.201379807Z' > '/home/node/.devcontainer/.onCreateCommandMarker'","startTimestamp":1744102135431}
{"type":"start","level":2,"timestamp":1744102135432,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.updateContentCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-07T09:21:41.201379807Z}\" != '2025-04-07T09:21:41.201379807Z' ] && echo '2025-04-07T09:21:41.201379807Z' > '/home/node/.devcontainer/.updateContentCommandMarker'"}
{"type":"text","level":2,"timestamp":1744102135434,"text":""}
{"type":"text","level":2,"timestamp":1744102135434,"text":""}
{"type":"text","level":2,"timestamp":1744102135434,"text":"Exit code 1"}
{"type":"stop","level":2,"timestamp":1744102135434,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.updateContentCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-07T09:21:41.201379807Z}\" != '2025-04-07T09:21:41.201379807Z' ] && echo '2025-04-07T09:21:41.201379807Z' > '/home/node/.devcontainer/.updateContentCommandMarker'","startTimestamp":1744102135432}
{"type":"start","level":2,"timestamp":1744102135434,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.postCreateCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-07T09:21:41.201379807Z}\" != '2025-04-07T09:21:41.201379807Z' ] && echo '2025-04-07T09:21:41.201379807Z' > '/home/node/.devcontainer/.postCreateCommandMarker'"}
{"type":"text","level":2,"timestamp":1744102135435,"text":""}
{"type":"text","level":2,"timestamp":1744102135435,"text":""}
{"type":"text","level":2,"timestamp":1744102135435,"text":"Exit code 1"}
{"type":"stop","level":2,"timestamp":1744102135435,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.postCreateCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-07T09:21:41.201379807Z}\" != '2025-04-07T09:21:41.201379807Z' ] && echo '2025-04-07T09:21:41.201379807Z' > '/home/node/.devcontainer/.postCreateCommandMarker'","startTimestamp":1744102135434}
{"type":"start","level":2,"timestamp":1744102135435,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.postStartCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-08T08:48:29.406495039Z}\" != '2025-04-08T08:48:29.406495039Z' ] && echo '2025-04-08T08:48:29.406495039Z' > '/home/node/.devcontainer/.postStartCommandMarker'"}
{"type":"text","level":2,"timestamp":1744102135436,"text":""}
{"type":"text","level":2,"timestamp":1744102135436,"text":""}
{"type":"text","level":2,"timestamp":1744102135436,"text":"Exit code 1"}
{"type":"stop","level":2,"timestamp":1744102135436,"text":"Run in container: mkdir -p '/home/node/.devcontainer' && CONTENT=\"$(cat '/home/node/.devcontainer/.postStartCommandMarker' 2>/dev/null || echo ENOENT)\" && [ \"${CONTENT:-2025-04-08T08:48:29.406495039Z}\" != '2025-04-08T08:48:29.406495039Z' ] && echo '2025-04-08T08:48:29.406495039Z' > '/home/node/.devcontainer/.postStartCommandMarker'","startTimestamp":1744102135435}
{"type":"stop","level":2,"timestamp":1744102135436,"text":"Resolving Remote","startTimestamp":1744102135309}
{"outcome":"success","containerId":"4f22413fe13472200500a66ca057df5aafba6b45743afd499c3f26fc886eb236","remoteUser":"node","remoteWorkspaceFolder":"/workspaces/devcontainers-template-starter"}
@@ -0,0 +1 @@
bad outcome
@@ -0,0 +1,13 @@
{"type":"text","level":3,"timestamp":1744102042893,"text":"@devcontainers/cli 0.75.0. Node.js v23.9.0. darwin 24.4.0 arm64."}
{"type":"start","level":2,"timestamp":1744102042893,"text":"Run: docker buildx version"}
{"type":"stop","level":2,"timestamp":1744102042941,"text":"Run: docker buildx version","startTimestamp":1744102042893}
{"type":"text","level":2,"timestamp":1744102042941,"text":"github.com/docker/buildx v0.21.2 1360a9e8d25a2c3d03c2776d53ae62e6ff0a843d\r\n"}
{"type":"text","level":2,"timestamp":1744102042941,"text":"\u001b[1m\u001b[31m\u001b[39m\u001b[22m\r\n"}
{"type":"start","level":2,"timestamp":1744102042941,"text":"Run: docker -v"}
{"type":"stop","level":2,"timestamp":1744102042950,"text":"Run: docker -v","startTimestamp":1744102042941}
{"type":"start","level":2,"timestamp":1744102042950,"text":"Resolving Remote"}
{"type":"start","level":2,"timestamp":1744102042952,"text":"Run: git rev-parse --show-cdup"}
{"type":"stop","level":2,"timestamp":1744102042957,"text":"Run: git rev-parse --show-cdup","startTimestamp":1744102042952}
{"type":"start","level":2,"timestamp":1744102042957,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/code/devcontainers-template-starter --filter label=devcontainer.config_file=/code/devcontainers-template-starter/.devcontainer/devcontainer.json"}
{"type":"stop","level":2,"timestamp":1744102042967,"text":"Run: docker ps -q -a --filter label=devcontainer.local_folder=/code/devcontainers-template-starter --filter label=devcontainer.config_file=/code/devcontainers-template-starter/.devcontainer/devcontainer.json","startTimestamp":1744102042957}
{"outcome":"error","message":"Command failed: docker ps -q -a --filter label=devcontainer.local_folder=/code/devcontainers-template-starter --filter label=devcontainer.config_file=/code/devcontainers-template-starter/.devcontainer/devcontainer.json","description":"An error occurred setting up the container."}
@@ -0,0 +1,15 @@
{"type":"text","level":3,"timestamp":1744102555495,"text":"@devcontainers/cli 0.75.0. Node.js v23.9.0. darwin 24.4.0 arm64."}
{"type":"start","level":2,"timestamp":1744102555495,"text":"Run: docker buildx version"}
{"type":"stop","level":2,"timestamp":1744102555539,"text":"Run: docker buildx version","startTimestamp":1744102555495}
{"type":"text","level":2,"timestamp":1744102555539,"text":"github.com/docker/buildx v0.21.2 1360a9e8d25a2c3d03c2776d53ae62e6ff0a843d\r\n"}
{"type":"text","level":2,"timestamp":1744102555539,"text":"\u001b[1m\u001b[31m\u001b[39m\u001b[22m\r\n"}
{"type":"start","level":2,"timestamp":1744102555539,"text":"Run: docker -v"}
{"type":"stop","level":2,"timestamp":1744102555548,"text":"Run: docker -v","startTimestamp":1744102555539}
{"type":"start","level":2,"timestamp":1744102555548,"text":"Resolving Remote"}
Error: Dev container config (/code/devcontainers-template-starter/foo/.devcontainer/devcontainer.json) not found.
at H6 (/opt/homebrew/Cellar/devcontainer/0.75.0/libexec/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:484:3219)
at async BC (/opt/homebrew/Cellar/devcontainer/0.75.0/libexec/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:484:4957)
at async d7 (/opt/homebrew/Cellar/devcontainer/0.75.0/libexec/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:665:202)
at async f7 (/opt/homebrew/Cellar/devcontainer/0.75.0/libexec/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:664:14804)
at async /opt/homebrew/Cellar/devcontainer/0.75.0/libexec/lib/node_modules/@devcontainers/cli/dist/spec-node/devContainersSpecCLI.js:484:1188
{"outcome":"error","message":"Dev container config (/code/devcontainers-template-starter/foo/.devcontainer/devcontainer.json) not found.","description":"Dev container config (/code/devcontainers-template-starter/foo/.devcontainer/devcontainer.json) not found."}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+48
View File
@@ -0,0 +1,48 @@
package watcher
import (
"context"
"sync"
"github.com/fsnotify/fsnotify"
)
// NewNoop creates a new watcher that does nothing.
func NewNoop() Watcher {
return &noopWatcher{done: make(chan struct{})}
}
type noopWatcher struct {
mu sync.Mutex
closed bool
done chan struct{}
}
func (*noopWatcher) Add(string) error {
return nil
}
func (*noopWatcher) Remove(string) error {
return nil
}
// Next blocks until the context is canceled or the watcher is closed.
func (n *noopWatcher) Next(ctx context.Context) (*fsnotify.Event, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-n.done:
return nil, ErrClosed
}
}
func (n *noopWatcher) Close() error {
n.mu.Lock()
defer n.mu.Unlock()
if n.closed {
return ErrClosed
}
n.closed = true
close(n.done)
return nil
}
@@ -0,0 +1,70 @@
package watcher_test
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/agent/agentcontainers/watcher"
"github.com/coder/coder/v2/testutil"
)
func TestNoopWatcher(t *testing.T) {
t.Parallel()
// Create the noop watcher under test.
wut := watcher.NewNoop()
// Test adding/removing files (should have no effect).
err := wut.Add("some-file.txt")
assert.NoError(t, err, "noop watcher should not return error on Add")
err = wut.Remove("some-file.txt")
assert.NoError(t, err, "noop watcher should not return error on Remove")
ctx, cancel := context.WithCancel(t.Context())
defer cancel()
// Start a goroutine to wait for Next to return.
errC := make(chan error, 1)
go func() {
_, err := wut.Next(ctx)
errC <- err
}()
select {
case <-errC:
require.Fail(t, "want Next to block")
default:
}
// Cancel the context and check that Next returns.
cancel()
select {
case err := <-errC:
assert.Error(t, err, "want Next error when context is canceled")
case <-time.After(testutil.WaitShort):
t.Fatal("want Next to return after context was canceled")
}
// Test Close.
err = wut.Close()
assert.NoError(t, err, "want no error on Close")
}
func TestNoopWatcher_CloseBeforeNext(t *testing.T) {
t.Parallel()
wut := watcher.NewNoop()
err := wut.Close()
require.NoError(t, err, "close watcher failed")
ctx := context.Background()
_, err = wut.Next(ctx)
assert.Error(t, err, "want Next to return error when watcher is closed")
}
+195
View File
@@ -0,0 +1,195 @@
// Package watcher provides file system watching capabilities for the
// agent. It defines an interface for monitoring file changes and
// implementations that can be used to detect when configuration files
// are modified. This is primarily used to track changes to devcontainer
// configuration files and notify users when containers need to be
// recreated to apply the new configuration.
package watcher
import (
"context"
"path/filepath"
"sync"
"github.com/fsnotify/fsnotify"
"golang.org/x/xerrors"
)
var ErrClosed = xerrors.New("watcher closed")
// Watcher defines an interface for monitoring file system changes.
// Implementations track file modifications and provide an event stream
// that clients can consume to react to changes.
type Watcher interface {
// Add starts watching a file for changes.
Add(file string) error
// Remove stops watching a file for changes.
Remove(file string) error
// Next blocks until a file system event occurs or the context is canceled.
// It returns the next event or an error if the watcher encountered a problem.
Next(context.Context) (*fsnotify.Event, error)
// Close shuts down the watcher and releases any resources.
Close() error
}
type fsnotifyWatcher struct {
*fsnotify.Watcher
mu sync.Mutex // Protects following.
watchedFiles map[string]bool // Files being watched (absolute path -> bool).
watchedDirs map[string]int // Refcount of directories being watched (absolute path -> count).
closed bool // Protects closing of done.
done chan struct{}
}
// NewFSNotify creates a new file system watcher that watches parent directories
// instead of individual files for more reliable event detection.
func NewFSNotify() (Watcher, error) {
w, err := fsnotify.NewWatcher()
if err != nil {
return nil, xerrors.Errorf("create fsnotify watcher: %w", err)
}
return &fsnotifyWatcher{
Watcher: w,
done: make(chan struct{}),
watchedFiles: make(map[string]bool),
watchedDirs: make(map[string]int),
}, nil
}
func (f *fsnotifyWatcher) Add(file string) error {
absPath, err := filepath.Abs(file)
if err != nil {
return xerrors.Errorf("absolute path: %w", err)
}
dir := filepath.Dir(absPath)
f.mu.Lock()
defer f.mu.Unlock()
// Already watching this file.
if f.closed || f.watchedFiles[absPath] {
return nil
}
// Start watching the parent directory if not already watching.
if f.watchedDirs[dir] == 0 {
if err := f.Watcher.Add(dir); err != nil {
return xerrors.Errorf("add directory to watcher: %w", err)
}
}
// Increment the reference count for this directory.
f.watchedDirs[dir]++
// Mark this file as watched.
f.watchedFiles[absPath] = true
return nil
}
func (f *fsnotifyWatcher) Remove(file string) error {
absPath, err := filepath.Abs(file)
if err != nil {
return xerrors.Errorf("absolute path: %w", err)
}
dir := filepath.Dir(absPath)
f.mu.Lock()
defer f.mu.Unlock()
// Not watching this file.
if f.closed || !f.watchedFiles[absPath] {
return nil
}
// Remove the file from our watch list.
delete(f.watchedFiles, absPath)
// Decrement the reference count for this directory.
f.watchedDirs[dir]--
// If no more files in this directory are being watched, stop
// watching the directory.
if f.watchedDirs[dir] <= 0 {
f.watchedDirs[dir] = 0 // Ensure non-negative count.
if err := f.Watcher.Remove(dir); err != nil {
return xerrors.Errorf("remove directory from watcher: %w", err)
}
delete(f.watchedDirs, dir)
}
return nil
}
func (f *fsnotifyWatcher) Next(ctx context.Context) (event *fsnotify.Event, err error) {
defer func() {
if ctx.Err() != nil {
event = nil
err = ctx.Err()
}
}()
for {
select {
case <-ctx.Done():
return nil, ctx.Err()
case evt, ok := <-f.Events:
if !ok {
return nil, ErrClosed
}
// Get the absolute path to match against our watched files.
absPath, err := filepath.Abs(evt.Name)
if err != nil {
continue
}
f.mu.Lock()
if f.closed {
f.mu.Unlock()
return nil, ErrClosed
}
isWatched := f.watchedFiles[absPath]
f.mu.Unlock()
if !isWatched {
continue // Ignore events for files not being watched.
}
return &evt, nil
case err, ok := <-f.Errors:
if !ok {
return nil, ErrClosed
}
return nil, xerrors.Errorf("watcher error: %w", err)
case <-f.done:
return nil, ErrClosed
}
}
}
func (f *fsnotifyWatcher) Close() (err error) {
f.mu.Lock()
f.watchedFiles = nil
f.watchedDirs = nil
closed := f.closed
f.closed = true
f.mu.Unlock()
if closed {
return ErrClosed
}
close(f.done)
if err := f.Watcher.Close(); err != nil {
return xerrors.Errorf("close watcher: %w", err)
}
return nil
}
@@ -0,0 +1,128 @@
package watcher_test
import (
"context"
"os"
"path/filepath"
"testing"
"github.com/fsnotify/fsnotify"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/agent/agentcontainers/watcher"
"github.com/coder/coder/v2/testutil"
)
func TestFSNotifyWatcher(t *testing.T) {
t.Parallel()
// Create test files.
dir := t.TempDir()
testFile := filepath.Join(dir, "test.json")
err := os.WriteFile(testFile, []byte(`{"test": "initial"}`), 0o600)
require.NoError(t, err, "create test file failed")
// Create the watcher under test.
wut, err := watcher.NewFSNotify()
require.NoError(t, err, "create FSNotify watcher failed")
defer wut.Close()
// Add the test file to the watch list.
err = wut.Add(testFile)
require.NoError(t, err, "add file to watcher failed")
ctx := testutil.Context(t, testutil.WaitShort)
// Modify the test file to trigger an event.
err = os.WriteFile(testFile, []byte(`{"test": "modified"}`), 0o600)
require.NoError(t, err, "modify test file failed")
// Verify that we receive the event we want.
for {
event, err := wut.Next(ctx)
require.NoError(t, err, "next event failed")
require.NotNil(t, event, "want non-nil event")
if !event.Has(fsnotify.Write) {
t.Logf("Ignoring event: %s", event)
continue
}
require.Truef(t, event.Has(fsnotify.Write), "want write event: %s", event.String())
require.Equal(t, event.Name, testFile, "want event for test file")
break
}
// Rename the test file to trigger a rename event.
err = os.Rename(testFile, testFile+".bak")
require.NoError(t, err, "rename test file failed")
// Verify that we receive the event we want.
for {
event, err := wut.Next(ctx)
require.NoError(t, err, "next event failed")
require.NotNil(t, event, "want non-nil event")
if !event.Has(fsnotify.Rename) {
t.Logf("Ignoring event: %s", event)
continue
}
require.Truef(t, event.Has(fsnotify.Rename), "want rename event: %s", event.String())
require.Equal(t, event.Name, testFile, "want event for test file")
break
}
err = os.WriteFile(testFile, []byte(`{"test": "new"}`), 0o600)
require.NoError(t, err, "write new test file failed")
// Verify that we receive the event we want.
for {
event, err := wut.Next(ctx)
require.NoError(t, err, "next event failed")
require.NotNil(t, event, "want non-nil event")
if !event.Has(fsnotify.Create) {
t.Logf("Ignoring event: %s", event)
continue
}
require.Truef(t, event.Has(fsnotify.Create), "want create event: %s", event.String())
require.Equal(t, event.Name, testFile, "want event for test file")
break
}
err = os.WriteFile(testFile+".atomic", []byte(`{"test": "atomic"}`), 0o600)
require.NoError(t, err, "write new atomic test file failed")
err = os.Rename(testFile+".atomic", testFile)
require.NoError(t, err, "rename atomic test file failed")
// Verify that we receive the event we want.
for {
event, err := wut.Next(ctx)
require.NoError(t, err, "next event failed")
require.NotNil(t, event, "want non-nil event")
if !event.Has(fsnotify.Create) {
t.Logf("Ignoring event: %s", event)
continue
}
require.Truef(t, event.Has(fsnotify.Create), "want create event: %s", event.String())
require.Equal(t, event.Name, testFile, "want event for test file")
break
}
// Test removing the file from the watcher.
err = wut.Remove(testFile)
require.NoError(t, err, "remove file from watcher failed")
}
func TestFSNotifyWatcher_CloseBeforeNext(t *testing.T) {
t.Parallel()
wut, err := watcher.NewFSNotify()
require.NoError(t, err, "create FSNotify watcher failed")
err = wut.Close()
require.NoError(t, err, "close watcher failed")
ctx := context.Background()
_, err = wut.Next(ctx)
assert.Error(t, err, "want Next to return error when watcher is closed")
}
+4 -1
View File
@@ -17,6 +17,8 @@ import (
"golang.org/x/sys/unix"
"golang.org/x/xerrors"
"kernel.org/pub/linux/libs/security/libcap/cap"
"github.com/coder/coder/v2/agent/usershell"
)
// CLI runs the agent-exec command. It should only be called by the cli package.
@@ -114,7 +116,8 @@ func CLI() error {
// Remove environment variables specific to the agentexec command. This is
// especially important for environments that are attempting to develop Coder in Coder.
env := os.Environ()
ei := usershell.SystemEnvInfo{}
env := ei.Environ()
env = slices.DeleteFunc(env, func(e string) bool {
return strings.HasPrefix(e, EnvProcPrioMgmt) ||
strings.HasPrefix(e, EnvProcOOMScore) ||
+87
View File
@@ -0,0 +1,87 @@
package agentrsa
import (
"crypto/rsa"
"math/big"
"math/rand"
)
// GenerateDeterministicKey generates an RSA private key deterministically based on the provided seed.
// This function uses a deterministic random source to generate the primes p and q, ensuring that the
// same seed will always produce the same private key. The generated key is 2048 bits in size.
//
// Reference: https://pkg.go.dev/crypto/rsa#GenerateKey
func GenerateDeterministicKey(seed int64) *rsa.PrivateKey {
// Since the standard lib purposefully does not generate
// deterministic rsa keys, we need to do it ourselves.
// Create deterministic random source
// nolint: gosec
deterministicRand := rand.New(rand.NewSource(seed))
// Use fixed values for p and q based on the seed
p := big.NewInt(0)
q := big.NewInt(0)
e := big.NewInt(65537) // Standard RSA public exponent
for {
// Generate deterministic primes using the seeded random
// Each prime should be ~1024 bits to get a 2048-bit key
for {
p.SetBit(p, 1024, 1) // Ensure it's large enough
for i := range 1024 {
if deterministicRand.Int63()%2 == 1 {
p.SetBit(p, i, 1)
} else {
p.SetBit(p, i, 0)
}
}
p1 := new(big.Int).Sub(p, big.NewInt(1))
if p.ProbablyPrime(20) && new(big.Int).GCD(nil, nil, e, p1).Cmp(big.NewInt(1)) == 0 {
break
}
}
for {
q.SetBit(q, 1024, 1) // Ensure it's large enough
for i := range 1024 {
if deterministicRand.Int63()%2 == 1 {
q.SetBit(q, i, 1)
} else {
q.SetBit(q, i, 0)
}
}
q1 := new(big.Int).Sub(q, big.NewInt(1))
if q.ProbablyPrime(20) && p.Cmp(q) != 0 && new(big.Int).GCD(nil, nil, e, q1).Cmp(big.NewInt(1)) == 0 {
break
}
}
// Calculate phi = (p-1) * (q-1)
p1 := new(big.Int).Sub(p, big.NewInt(1))
q1 := new(big.Int).Sub(q, big.NewInt(1))
phi := new(big.Int).Mul(p1, q1)
// Calculate private exponent d
d := new(big.Int).ModInverse(e, phi)
if d != nil {
// Calculate n = p * q
n := new(big.Int).Mul(p, q)
// Create the private key
privateKey := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: n,
E: int(e.Int64()),
},
D: d,
Primes: []*big.Int{p, q},
}
// Compute precomputed values
privateKey.Precompute()
return privateKey
}
}
}
+51
View File
@@ -0,0 +1,51 @@
package agentrsa_test
import (
"crypto/rsa"
"math/rand/v2"
"testing"
"github.com/stretchr/testify/assert"
"github.com/coder/coder/v2/agent/agentrsa"
)
func TestGenerateDeterministicKey(t *testing.T) {
t.Parallel()
key1 := agentrsa.GenerateDeterministicKey(1234)
key2 := agentrsa.GenerateDeterministicKey(1234)
assert.Equal(t, key1, key2)
assert.EqualExportedValues(t, key1, key2)
}
var result *rsa.PrivateKey
func BenchmarkGenerateDeterministicKey(b *testing.B) {
var r *rsa.PrivateKey
for range b.N {
// always record the result of DeterministicPrivateKey to prevent
// the compiler eliminating the function call.
// #nosec G404 - Using math/rand is acceptable for benchmarking deterministic keys
r = agentrsa.GenerateDeterministicKey(rand.Int64())
}
// always store the result to a package level variable
// so the compiler cannot eliminate the Benchmark itself.
result = r
}
func FuzzGenerateDeterministicKey(f *testing.F) {
testcases := []int64{0, 1234, 1010101010}
for _, tc := range testcases {
f.Add(tc) // Use f.Add to provide a seed corpus
}
f.Fuzz(func(t *testing.T, seed int64) {
key1 := agentrsa.GenerateDeterministicKey(seed)
key2 := agentrsa.GenerateDeterministicKey(seed)
assert.Equal(t, key1, key2)
assert.EqualExportedValues(t, key1, key2)
})
}
+61 -10
View File
@@ -10,7 +10,6 @@ import (
"os/user"
"path/filepath"
"sync"
"sync/atomic"
"time"
"github.com/google/uuid"
@@ -80,6 +79,21 @@ func New(opts Options) *Runner {
type ScriptCompletedFunc func(context.Context, *proto.WorkspaceAgentScriptCompletedRequest) (*proto.WorkspaceAgentScriptCompletedResponse, error)
type runnerScript struct {
runOnPostStart bool
codersdk.WorkspaceAgentScript
}
func toRunnerScript(scripts ...codersdk.WorkspaceAgentScript) []runnerScript {
var rs []runnerScript
for _, s := range scripts {
rs = append(rs, runnerScript{
WorkspaceAgentScript: s,
})
}
return rs
}
type Runner struct {
Options
@@ -89,8 +103,7 @@ type Runner struct {
closed chan struct{}
closeMutex sync.Mutex
cron *cron.Cron
initialized atomic.Bool
scripts []codersdk.WorkspaceAgentScript
scripts []runnerScript
dataDir string
scriptCompleted ScriptCompletedFunc
@@ -98,6 +111,9 @@ type Runner struct {
// execute startup scripts, and scripts on a cron schedule. Both will increment
// this counter.
scriptsExecuted *prometheus.CounterVec
initMutex sync.Mutex
initialized bool
}
// DataDir returns the directory where scripts data is stored.
@@ -119,16 +135,37 @@ func (r *Runner) RegisterMetrics(reg prometheus.Registerer) {
reg.MustRegister(r.scriptsExecuted)
}
// InitOption describes an option for the runner initialization.
type InitOption func(*Runner)
// WithPostStartScripts adds scripts that should be run after the workspace
// start scripts but before the workspace is marked as started.
func WithPostStartScripts(scripts ...codersdk.WorkspaceAgentScript) InitOption {
return func(r *Runner) {
for _, s := range scripts {
r.scripts = append(r.scripts, runnerScript{
runOnPostStart: true,
WorkspaceAgentScript: s,
})
}
}
}
// Init initializes the runner with the provided scripts.
// It also schedules any scripts that have a schedule.
// This function must be called before Execute.
func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript, scriptCompleted ScriptCompletedFunc) error {
if r.initialized.Load() {
func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript, scriptCompleted ScriptCompletedFunc, opts ...InitOption) error {
r.initMutex.Lock()
defer r.initMutex.Unlock()
if r.initialized {
return xerrors.New("init: already initialized")
}
r.initialized.Store(true)
r.scripts = scripts
r.initialized = true
r.scripts = toRunnerScript(scripts...)
r.scriptCompleted = scriptCompleted
for _, opt := range opts {
opt(r)
}
r.Logger.Info(r.cronCtx, "initializing agent scripts", slog.F("script_count", len(scripts)), slog.F("log_dir", r.LogDir))
err := r.Filesystem.MkdirAll(r.ScriptBinDir(), 0o700)
@@ -136,13 +173,13 @@ func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript, scriptCompleted S
return xerrors.Errorf("create script bin dir: %w", err)
}
for _, script := range scripts {
for _, script := range r.scripts {
if script.Cron == "" {
continue
}
script := script
_, err := r.cron.AddFunc(script.Cron, func() {
err := r.trackRun(r.cronCtx, script, ExecuteCronScripts)
err := r.trackRun(r.cronCtx, script.WorkspaceAgentScript, ExecuteCronScripts)
if err != nil {
r.Logger.Warn(context.Background(), "run agent script on schedule", slog.Error(err))
}
@@ -186,16 +223,30 @@ type ExecuteOption int
const (
ExecuteAllScripts ExecuteOption = iota
ExecuteStartScripts
ExecutePostStartScripts
ExecuteStopScripts
ExecuteCronScripts
)
// Execute runs a set of scripts according to a filter.
func (r *Runner) Execute(ctx context.Context, option ExecuteOption) error {
initErr := func() error {
r.initMutex.Lock()
defer r.initMutex.Unlock()
if !r.initialized {
return xerrors.New("execute: not initialized")
}
return nil
}()
if initErr != nil {
return initErr
}
var eg errgroup.Group
for _, script := range r.scripts {
runScript := (option == ExecuteStartScripts && script.RunOnStart) ||
(option == ExecuteStopScripts && script.RunOnStop) ||
(option == ExecutePostStartScripts && script.runOnPostStart) ||
(option == ExecuteCronScripts && script.Cron != "") ||
option == ExecuteAllScripts
@@ -205,7 +256,7 @@ func (r *Runner) Execute(ctx context.Context, option ExecuteOption) error {
script := script
eg.Go(func() error {
err := r.trackRun(ctx, script, option)
err := r.trackRun(ctx, script.WorkspaceAgentScript, option)
if err != nil {
return xerrors.Errorf("run agent script %q: %w", script.LogSourceID, err)
}
+158 -4
View File
@@ -4,6 +4,8 @@ import (
"context"
"path/filepath"
"runtime"
"slices"
"sync"
"testing"
"time"
@@ -42,7 +44,7 @@ func TestExecuteBasic(t *testing.T) {
}}, aAPI.ScriptCompleted)
require.NoError(t, err)
require.NoError(t, runner.Execute(context.Background(), agentscripts.ExecuteAllScripts))
log := testutil.RequireRecvCtx(ctx, t, fLogger.logs)
log := testutil.TryReceive(ctx, t, fLogger.logs)
require.Equal(t, "hello", log.Output)
}
@@ -100,13 +102,16 @@ func TestEnv(t *testing.T) {
func TestTimeout(t *testing.T) {
t.Parallel()
if runtime.GOOS == "darwin" {
t.Skip("this test is flaky on macOS, see https://github.com/coder/internal/issues/329")
}
runner := setup(t, nil)
defer runner.Close()
aAPI := agenttest.NewFakeAgentAPI(t, testutil.Logger(t), nil, nil)
err := runner.Init([]codersdk.WorkspaceAgentScript{{
LogSourceID: uuid.New(),
Script: "sleep infinity",
Timeout: time.Millisecond,
Timeout: 100 * time.Millisecond,
}}, aAPI.ScriptCompleted)
require.NoError(t, err)
require.ErrorIs(t, runner.Execute(context.Background(), agentscripts.ExecuteAllScripts), agentscripts.ErrTimeout)
@@ -131,7 +136,7 @@ func TestScriptReportsTiming(t *testing.T) {
require.NoError(t, runner.Execute(ctx, agentscripts.ExecuteAllScripts))
runner.Close()
log := testutil.RequireRecvCtx(ctx, t, fLogger.logs)
log := testutil.TryReceive(ctx, t, fLogger.logs)
require.Equal(t, "hello", log.Output)
timings := aAPI.GetTimings()
@@ -151,11 +156,160 @@ func TestCronClose(t *testing.T) {
require.NoError(t, runner.Close(), "close runner")
}
func TestExecuteOptions(t *testing.T) {
t.Parallel()
startScript := codersdk.WorkspaceAgentScript{
ID: uuid.New(),
LogSourceID: uuid.New(),
Script: "echo start",
RunOnStart: true,
}
stopScript := codersdk.WorkspaceAgentScript{
ID: uuid.New(),
LogSourceID: uuid.New(),
Script: "echo stop",
RunOnStop: true,
}
postStartScript := codersdk.WorkspaceAgentScript{
ID: uuid.New(),
LogSourceID: uuid.New(),
Script: "echo poststart",
}
regularScript := codersdk.WorkspaceAgentScript{
ID: uuid.New(),
LogSourceID: uuid.New(),
Script: "echo regular",
}
scripts := []codersdk.WorkspaceAgentScript{
startScript,
stopScript,
regularScript,
}
allScripts := append(slices.Clone(scripts), postStartScript)
scriptByID := func(t *testing.T, id uuid.UUID) codersdk.WorkspaceAgentScript {
for _, script := range allScripts {
if script.ID == id {
return script
}
}
t.Fatal("script not found")
return codersdk.WorkspaceAgentScript{}
}
wantOutput := map[uuid.UUID]string{
startScript.ID: "start",
stopScript.ID: "stop",
postStartScript.ID: "poststart",
regularScript.ID: "regular",
}
testCases := []struct {
name string
option agentscripts.ExecuteOption
wantRun []uuid.UUID
}{
{
name: "ExecuteAllScripts",
option: agentscripts.ExecuteAllScripts,
wantRun: []uuid.UUID{startScript.ID, stopScript.ID, regularScript.ID, postStartScript.ID},
},
{
name: "ExecuteStartScripts",
option: agentscripts.ExecuteStartScripts,
wantRun: []uuid.UUID{startScript.ID},
},
{
name: "ExecutePostStartScripts",
option: agentscripts.ExecutePostStartScripts,
wantRun: []uuid.UUID{postStartScript.ID},
},
{
name: "ExecuteStopScripts",
option: agentscripts.ExecuteStopScripts,
wantRun: []uuid.UUID{stopScript.ID},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t, testutil.WaitMedium)
executedScripts := make(map[uuid.UUID]bool)
fLogger := &executeOptionTestLogger{
tb: t,
executedScripts: executedScripts,
wantOutput: wantOutput,
}
runner := setup(t, func(uuid.UUID) agentscripts.ScriptLogger {
return fLogger
})
defer runner.Close()
aAPI := agenttest.NewFakeAgentAPI(t, testutil.Logger(t), nil, nil)
err := runner.Init(
scripts,
aAPI.ScriptCompleted,
agentscripts.WithPostStartScripts(postStartScript),
)
require.NoError(t, err)
err = runner.Execute(ctx, tc.option)
require.NoError(t, err)
gotRun := map[uuid.UUID]bool{}
for _, id := range tc.wantRun {
gotRun[id] = true
require.True(t, executedScripts[id],
"script %s should have run when using filter %s", scriptByID(t, id).Script, tc.name)
}
for _, script := range allScripts {
if _, ok := gotRun[script.ID]; ok {
continue
}
require.False(t, executedScripts[script.ID],
"script %s should not have run when using filter %s", script.Script, tc.name)
}
})
}
}
type executeOptionTestLogger struct {
tb testing.TB
executedScripts map[uuid.UUID]bool
wantOutput map[uuid.UUID]string
mu sync.Mutex
}
func (l *executeOptionTestLogger) Send(_ context.Context, logs ...agentsdk.Log) error {
l.mu.Lock()
defer l.mu.Unlock()
for _, log := range logs {
l.tb.Log(log.Output)
for id, output := range l.wantOutput {
if log.Output == output {
l.executedScripts[id] = true
break
}
}
}
return nil
}
func (*executeOptionTestLogger) Flush(context.Context) error {
return nil
}
func setup(t *testing.T, getScriptLogger func(logSourceID uuid.UUID) agentscripts.ScriptLogger) *agentscripts.Runner {
t.Helper()
if getScriptLogger == nil {
// noop
getScriptLogger = func(uuid uuid.UUID) agentscripts.ScriptLogger {
getScriptLogger = func(uuid.UUID) agentscripts.ScriptLogger {
return noopScriptLogger{}
}
}
+258 -157
View File
@@ -3,18 +3,16 @@ package agentssh
import (
"bufio"
"context"
"crypto/rsa"
"errors"
"fmt"
"io"
"math/big"
"math/rand"
"net"
"os"
"os/exec"
"os/user"
"path/filepath"
"runtime"
"slices"
"strings"
"sync"
"time"
@@ -27,12 +25,13 @@ import (
"github.com/spf13/afero"
"go.uber.org/atomic"
gossh "golang.org/x/crypto/ssh"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"cdr.dev/slog"
"github.com/coder/coder/v2/agent/agentcontainers"
"github.com/coder/coder/v2/agent/agentexec"
"github.com/coder/coder/v2/agent/agentrsa"
"github.com/coder/coder/v2/agent/usershell"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/pty"
@@ -62,6 +61,14 @@ const (
// MagicSessionTypeEnvironmentVariable is used to track the purpose behind an SSH connection.
// This is stripped from any commands being executed, and is counted towards connection stats.
MagicSessionTypeEnvironmentVariable = "CODER_SSH_SESSION_TYPE"
// ContainerEnvironmentVariable is used to specify the target container for an SSH connection.
// This is stripped from any commands being executed.
// Only available if CODER_AGENT_DEVCONTAINERS_ENABLE=true.
ContainerEnvironmentVariable = "CODER_CONTAINER"
// ContainerUserEnvironmentVariable is used to specify the container user for
// an SSH connection.
// Only available if CODER_AGENT_DEVCONTAINERS_ENABLE=true.
ContainerUserEnvironmentVariable = "CODER_CONTAINER_USER"
)
// MagicSessionType enums.
@@ -80,6 +87,8 @@ const (
// BlockedFileTransferCommands contains a list of restricted file transfer commands.
var BlockedFileTransferCommands = []string{"nc", "rsync", "scp", "sftp"}
type reportConnectionFunc func(id uuid.UUID, sessionType MagicSessionType, ip string) (disconnected func(code int, reason string))
// Config sets configuration parameters for the agent SSH server.
type Config struct {
// MaxTimeout sets the absolute connection timeout, none if empty. If set to
@@ -102,6 +111,11 @@ type Config struct {
X11DisplayOffset *int
// BlockFileTransfer restricts use of file transfer applications.
BlockFileTransfer bool
// ReportConnection.
ReportConnection reportConnectionFunc
// Experimental: allow connecting to running containers if
// CODER_AGENT_DEVCONTAINERS_ENABLE=true.
ExperimentalDevContainersEnabled bool
}
type Server struct {
@@ -110,6 +124,7 @@ type Server struct {
listeners map[net.Listener]struct{}
conns map[net.Conn]struct{}
sessions map[ssh.Session]struct{}
processes map[*os.Process]struct{}
closing chan struct{}
// Wait for goroutines to exit, waited without
// a lock on mu but protected by closing.
@@ -154,6 +169,9 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom
return home
}
}
if config.ReportConnection == nil {
config.ReportConnection = func(uuid.UUID, MagicSessionType, string) func(int, string) { return func(int, string) {} }
}
forwardHandler := &ssh.ForwardedTCPHandler{}
unixForwardHandler := newForwardedUnixHandler(logger)
@@ -165,6 +183,7 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom
fs: fs,
conns: make(map[net.Conn]struct{}),
sessions: make(map[ssh.Session]struct{}),
processes: make(map[*os.Process]struct{}),
logger: logger,
config: config,
@@ -176,7 +195,7 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom
ChannelHandlers: map[string]ssh.ChannelHandler{
"direct-tcpip": func(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context) {
// Wrapper is designed to find and track JetBrains Gateway connections.
wrapped := NewJetbrainsChannelWatcher(ctx, s.logger, newChan, &s.connCountJetBrains)
wrapped := NewJetbrainsChannelWatcher(ctx, s.logger, s.config.ReportConnection, newChan, &s.connCountJetBrains)
ssh.DirectTCPIPHandler(srv, conn, wrapped, ctx)
},
"direct-streamlocal@openssh.com": directStreamLocalHandler,
@@ -206,7 +225,7 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom
slog.F("destination_port", destinationPort))
return true
},
PtyCallback: func(ctx ssh.Context, pty ssh.Pty) bool {
PtyCallback: func(_ ssh.Context, _ ssh.Pty) bool {
return true
},
ReversePortForwardingCallback: func(ctx ssh.Context, bindHost string, bindPort uint32) bool {
@@ -223,7 +242,7 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom
"cancel-streamlocal-forward@openssh.com": unixForwardHandler.HandleSSHRequest,
},
X11Callback: s.x11Callback,
ServerConfigCallback: func(ctx ssh.Context) *gossh.ServerConfig {
ServerConfigCallback: func(_ ssh.Context) *gossh.ServerConfig {
return &gossh.ServerConfig{
NoClientAuth: true,
}
@@ -290,6 +309,51 @@ func extractMagicSessionType(env []string) (magicType MagicSessionType, rawType
})
}
// sessionCloseTracker is a wrapper around Session that tracks the exit code.
type sessionCloseTracker struct {
ssh.Session
exitOnce sync.Once
code atomic.Int64
}
var _ ssh.Session = &sessionCloseTracker{}
func (s *sessionCloseTracker) track(code int) {
s.exitOnce.Do(func() {
s.code.Store(int64(code))
})
}
func (s *sessionCloseTracker) exitCode() int {
return int(s.code.Load())
}
func (s *sessionCloseTracker) Exit(code int) error {
s.track(code)
return s.Session.Exit(code)
}
func (s *sessionCloseTracker) Close() error {
s.track(1)
return s.Session.Close()
}
func extractContainerInfo(env []string) (container, containerUser string, filteredEnv []string) {
for _, kv := range env {
if strings.HasPrefix(kv, ContainerEnvironmentVariable+"=") {
container = strings.TrimPrefix(kv, ContainerEnvironmentVariable+"=")
}
if strings.HasPrefix(kv, ContainerUserEnvironmentVariable+"=") {
containerUser = strings.TrimPrefix(kv, ContainerUserEnvironmentVariable+"=")
}
}
return container, containerUser, slices.DeleteFunc(env, func(kv string) bool {
return strings.HasPrefix(kv, ContainerEnvironmentVariable+"=") || strings.HasPrefix(kv, ContainerUserEnvironmentVariable+"=")
})
}
func (s *Server) sessionHandler(session ssh.Session) {
ctx := session.Context()
id := uuid.New()
@@ -302,16 +366,23 @@ func (s *Server) sessionHandler(session ssh.Session) {
)
logger.Info(ctx, "handling ssh session")
env := session.Environ()
magicType, magicTypeRaw, env := extractMagicSessionType(env)
if !s.trackSession(session, true) {
reason := "unable to accept new session, server is closing"
// Report connection attempt even if we couldn't accept it.
disconnected := s.config.ReportConnection(id, magicType, session.RemoteAddr().String())
defer disconnected(1, reason)
logger.Info(ctx, reason)
// See (*Server).Close() for why we call Close instead of Exit.
_ = session.Close()
logger.Info(ctx, "unable to accept new session, server is closing")
return
}
defer s.trackSession(session, false)
env := session.Environ()
magicType, magicTypeRaw, env := extractMagicSessionType(env)
reportSession := true
switch magicType {
case MagicSessionTypeVSCode:
@@ -320,6 +391,7 @@ func (s *Server) sessionHandler(session ssh.Session) {
case MagicSessionTypeJetBrains:
// Do nothing here because JetBrains launches hundreds of ssh sessions.
// We instead track JetBrains in the single persistent tcp forwarding channel.
reportSession = false
case MagicSessionTypeSSH:
s.connCountSSHSession.Add(1)
defer s.connCountSSHSession.Add(-1)
@@ -327,6 +399,20 @@ func (s *Server) sessionHandler(session ssh.Session) {
logger.Warn(ctx, "invalid magic ssh session type specified", slog.F("raw_type", magicTypeRaw))
}
closeCause := func(string) {}
if reportSession {
var reason string
closeCause = func(r string) { reason = r }
scr := &sessionCloseTracker{Session: session}
session = scr
disconnected := s.config.ReportConnection(id, magicType, session.RemoteAddr().String())
defer func() {
disconnected(scr.exitCode(), reason)
}()
}
if s.fileTransferBlocked(session) {
s.logger.Warn(ctx, "file transfer blocked", slog.F("session_subsystem", session.Subsystem()), slog.F("raw_command", session.RawCommand()))
@@ -335,17 +421,35 @@ func (s *Server) sessionHandler(session ssh.Session) {
errorMessage := fmt.Sprintf("\x02%s\n", BlockedFileTransferErrorMessage)
_, _ = session.Write([]byte(errorMessage))
}
closeCause("file transfer blocked")
_ = session.Exit(BlockedFileTransferErrorCode)
return
}
container, containerUser, env := extractContainerInfo(env)
if container != "" {
s.logger.Debug(ctx, "container info",
slog.F("container", container),
slog.F("container_user", containerUser),
)
}
switch ss := session.Subsystem(); ss {
case "":
case "sftp":
s.sftpHandler(logger, session)
if s.config.ExperimentalDevContainersEnabled && container != "" {
closeCause("sftp not yet supported with containers")
_ = session.Exit(1)
return
}
err := s.sftpHandler(logger, session)
if err != nil {
closeCause(err.Error())
}
return
default:
logger.Warn(ctx, "unsupported subsystem", slog.F("subsystem", ss))
closeCause(fmt.Sprintf("unsupported subsystem: %s", ss))
_ = session.Exit(1)
return
}
@@ -354,14 +458,15 @@ func (s *Server) sessionHandler(session ssh.Session) {
if hasX11 {
display, handled := s.x11Handler(session.Context(), x11)
if !handled {
_ = session.Exit(1)
logger.Error(ctx, "x11 handler failed")
closeCause("x11 handler failed")
_ = session.Exit(1)
return
}
env = append(env, fmt.Sprintf("DISPLAY=localhost:%d.%d", display, x11.ScreenNumber))
}
err := s.sessionStart(logger, session, env, magicType)
err := s.sessionStart(logger, session, env, magicType, container, containerUser)
var exitError *exec.ExitError
if xerrors.As(err, &exitError) {
code := exitError.ExitCode()
@@ -382,6 +487,8 @@ func (s *Server) sessionHandler(session ssh.Session) {
slog.F("exit_code", code),
)
closeCause(fmt.Sprintf("process exited with error status: %d", exitError.ExitCode()))
// TODO(mafredri): For signal exit, there's also an "exit-signal"
// request (session.Exit sends "exit-status"), however, since it's
// not implemented on the session interface and not used by
@@ -393,6 +500,7 @@ func (s *Server) sessionHandler(session ssh.Session) {
logger.Warn(ctx, "ssh session failed", slog.Error(err))
// This exit code is designed to be unlikely to be confused for a legit exit code
// from the process.
closeCause(err.Error())
_ = session.Exit(MagicSessionErrorCode)
return
}
@@ -431,18 +539,27 @@ func (s *Server) fileTransferBlocked(session ssh.Session) bool {
return false
}
func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []string, magicType MagicSessionType) (retErr error) {
func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []string, magicType MagicSessionType, container, containerUser string) (retErr error) {
ctx := session.Context()
magicTypeLabel := magicTypeMetricLabel(magicType)
sshPty, windowSize, isPty := session.Pty()
ptyLabel := "no"
if isPty {
ptyLabel = "yes"
}
cmd, err := s.CreateCommand(ctx, session.RawCommand(), env, nil)
if err != nil {
ptyLabel := "no"
if isPty {
ptyLabel = "yes"
var ei usershell.EnvInfoer
var err error
if s.config.ExperimentalDevContainersEnabled && container != "" {
ei, err = agentcontainers.EnvInfo(ctx, s.Execer, container, containerUser)
if err != nil {
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, ptyLabel, "container_env_info").Add(1)
return err
}
}
cmd, err := s.CreateCommand(ctx, session.RawCommand(), env, ei)
if err != nil {
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, ptyLabel, "create_command").Add(1)
return err
}
@@ -450,11 +567,6 @@ func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []str
if ssh.AgentRequested(session) {
l, err := ssh.NewAgentListener()
if err != nil {
ptyLabel := "no"
if isPty {
ptyLabel = "yes"
}
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, ptyLabel, "listener").Add(1)
return xerrors.Errorf("new agent listener: %w", err)
}
@@ -472,6 +584,15 @@ func (s *Server) sessionStart(logger slog.Logger, session ssh.Session, env []str
func (s *Server) startNonPTYSession(logger slog.Logger, session ssh.Session, magicTypeLabel string, cmd *exec.Cmd) error {
s.metrics.sessionsTotal.WithLabelValues(magicTypeLabel, "no").Add(1)
// Create a process group and send SIGHUP to child processes,
// otherwise context cancellation will not propagate properly
// and SSH server close may be delayed.
cmd.SysProcAttr = cmdSysProcAttr()
// to match OpenSSH, we don't actually tear a non-TTY command down, even if the session ends.
// c.f. https://github.com/coder/coder/issues/18519#issuecomment-3019118271
cmd.Cancel = nil
cmd.Stdout = session
cmd.Stderr = session.Stderr()
// This blocks forever until stdin is received if we don't
@@ -493,6 +614,16 @@ func (s *Server) startNonPTYSession(logger slog.Logger, session ssh.Session, mag
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, "no", "start_command").Add(1)
return xerrors.Errorf("start: %w", err)
}
// Since we don't cancel the process when the session stops, we still need to tear it down if we are closing. So
// track it here.
if !s.trackProcess(cmd.Process, true) {
// must be closing
err = cmdCancel(logger, cmd.Process)
return xerrors.Errorf("failed to track process: %w", err)
}
defer s.trackProcess(cmd.Process, false)
sigs := make(chan ssh.Signal, 1)
session.Signals(sigs)
defer func() {
@@ -592,6 +723,7 @@ func (s *Server) startPTYSession(logger slog.Logger, session ptySession, magicTy
windowSize = nil
continue
}
// #nosec G115 - Safe conversions for terminal dimensions which are expected to be within uint16 range
resizeErr := ptty.Resize(uint16(win.Height), uint16(win.Width))
// If the pty is closed, then command has exited, no need to log.
if resizeErr != nil && !errors.Is(resizeErr, pty.ErrClosed) {
@@ -652,7 +784,7 @@ func handleSignal(logger slog.Logger, ssig ssh.Signal, signaler interface{ Signa
}
}
func (s *Server) sftpHandler(logger slog.Logger, session ssh.Session) {
func (s *Server) sftpHandler(logger slog.Logger, session ssh.Session) error {
s.metrics.sftpConnectionsTotal.Add(1)
ctx := session.Context()
@@ -676,7 +808,7 @@ func (s *Server) sftpHandler(logger slog.Logger, session ssh.Session) {
server, err := sftp.NewServer(session, opts...)
if err != nil {
logger.Debug(ctx, "initialize sftp server", slog.Error(err))
return
return xerrors.Errorf("initialize sftp server: %w", err)
}
defer server.Close()
@@ -691,50 +823,12 @@ func (s *Server) sftpHandler(logger slog.Logger, session ssh.Session) {
// code but `scp` on macOS does (when using the default
// SFTP backend).
_ = session.Exit(0)
return
return nil
}
logger.Warn(ctx, "sftp server closed with error", slog.Error(err))
s.metrics.sftpServerErrors.Add(1)
_ = session.Exit(1)
}
// EnvInfoer encapsulates external information required by CreateCommand.
type EnvInfoer interface {
// CurrentUser returns the current user.
CurrentUser() (*user.User, error)
// Environ returns the environment variables of the current process.
Environ() []string
// UserHomeDir returns the home directory of the current user.
UserHomeDir() (string, error)
// UserShell returns the shell of the given user.
UserShell(username string) (string, error)
}
type systemEnvInfoer struct{}
var defaultEnvInfoer EnvInfoer = &systemEnvInfoer{}
// DefaultEnvInfoer returns a default implementation of
// EnvInfoer. This reads information using the default Go
// implementations.
func DefaultEnvInfoer() EnvInfoer {
return defaultEnvInfoer
}
func (systemEnvInfoer) CurrentUser() (*user.User, error) {
return user.Current()
}
func (systemEnvInfoer) Environ() []string {
return os.Environ()
}
func (systemEnvInfoer) UserHomeDir() (string, error) {
return userHomeDir()
}
func (systemEnvInfoer) UserShell(username string) (string, error) {
return usershell.Get(username)
return xerrors.Errorf("sftp server closed with error: %w", err)
}
// CreateCommand processes raw command input with OpenSSH-like behavior.
@@ -744,17 +838,17 @@ func (systemEnvInfoer) UserShell(username string) (string, error) {
// alternative implementations for the dependencies of CreateCommand.
// This is useful when creating a command to be run in a separate environment
// (for example, a Docker container). Pass in nil to use the default.
func (s *Server) CreateCommand(ctx context.Context, script string, env []string, deps EnvInfoer) (*pty.Cmd, error) {
if deps == nil {
deps = DefaultEnvInfoer()
func (s *Server) CreateCommand(ctx context.Context, script string, env []string, ei usershell.EnvInfoer) (*pty.Cmd, error) {
if ei == nil {
ei = &usershell.SystemEnvInfo{}
}
currentUser, err := deps.CurrentUser()
currentUser, err := ei.User()
if err != nil {
return nil, xerrors.Errorf("get current user: %w", err)
}
username := currentUser.Username
shell, err := deps.UserShell(username)
shell, err := ei.Shell(username)
if err != nil {
return nil, xerrors.Errorf("get user shell: %w", err)
}
@@ -802,7 +896,18 @@ func (s *Server) CreateCommand(ctx context.Context, script string, env []string,
}
}
cmd := s.Execer.PTYCommandContext(ctx, name, args...)
// Modify command prior to execution. This will usually be a no-op, but not
// always. For example, to run a command in a Docker container, we need to
// modify the command to be `docker exec -it <container> <command>`.
modifiedName, modifiedArgs := ei.ModifyCommand(name, args...)
// Log if the command was modified.
if modifiedName != name && slices.Compare(modifiedArgs, args) != 0 {
s.logger.Debug(ctx, "modified command",
slog.F("before", append([]string{name}, args...)),
slog.F("after", append([]string{modifiedName}, modifiedArgs...)),
)
}
cmd := s.Execer.PTYCommandContext(ctx, modifiedName, modifiedArgs...)
cmd.Dir = s.config.WorkingDirectory()
// If the metadata directory doesn't exist, we run the command
@@ -810,14 +915,17 @@ func (s *Server) CreateCommand(ctx context.Context, script string, env []string,
_, err = os.Stat(cmd.Dir)
if cmd.Dir == "" || err != nil {
// Default to user home if a directory is not set.
homedir, err := deps.UserHomeDir()
homedir, err := ei.HomeDir()
if err != nil {
return nil, xerrors.Errorf("get home dir: %w", err)
}
cmd.Dir = homedir
}
cmd.Env = append(deps.Environ(), env...)
cmd.Env = append(ei.Environ(), env...)
// Set login variables (see `man login`).
cmd.Env = append(cmd.Env, fmt.Sprintf("USER=%s", username))
cmd.Env = append(cmd.Env, fmt.Sprintf("LOGNAME=%s", username))
cmd.Env = append(cmd.Env, fmt.Sprintf("SHELL=%s", shell))
// Set SSH connection environment variables (these are also set by OpenSSH
// and thus expected to be present by SSH clients). Since the agent does
@@ -839,7 +947,12 @@ func (s *Server) CreateCommand(ctx context.Context, script string, env []string,
// Serve starts the server to handle incoming connections on the provided listener.
// It returns an error if no host keys are set or if there is an issue accepting connections.
func (s *Server) Serve(l net.Listener) (retErr error) {
if len(s.srv.HostSigners) == 0 {
// Ensure we're not mutating HostSigners as we're reading it.
s.mu.RLock()
noHostKeys := len(s.srv.HostSigners) == 0
s.mu.RUnlock()
if noHostKeys {
return xerrors.New("no host keys set")
}
@@ -954,6 +1067,27 @@ func (s *Server) trackSession(ss ssh.Session, add bool) (ok bool) {
return true
}
// trackCommand registers the process with the server. If the server is
// closing, the process is not registered and should be closed.
//
//nolint:revive
func (s *Server) trackProcess(p *os.Process, add bool) (ok bool) {
s.mu.Lock()
defer s.mu.Unlock()
if add {
if s.closing != nil {
// Server closed.
return false
}
s.wg.Add(1)
s.processes[p] = struct{}{}
return true
}
s.wg.Done()
delete(s.processes, p)
return true
}
// Close the server and all active connections. Server can be re-used
// after Close is done.
func (s *Server) Close() error {
@@ -962,32 +1096,47 @@ func (s *Server) Close() error {
// Guard against multiple calls to Close and
// accepting new connections during close.
if s.closing != nil {
closing := s.closing
s.mu.Unlock()
return xerrors.New("server is closing")
<-closing
return xerrors.New("server is closed")
}
s.closing = make(chan struct{})
ctx := context.Background()
s.logger.Debug(ctx, "closing server")
// Stop accepting new connections.
s.logger.Debug(ctx, "closing all active listeners", slog.F("count", len(s.listeners)))
for l := range s.listeners {
_ = l.Close()
}
// Close all active sessions to gracefully
// terminate client connections.
s.logger.Debug(ctx, "closing all active sessions", slog.F("count", len(s.sessions)))
for ss := range s.sessions {
// We call Close on the underlying channel here because we don't
// want to send an exit status to the client (via Exit()).
// Typically OpenSSH clients will return 255 as the exit status.
_ = ss.Close()
}
// Close all active listeners and connections.
for l := range s.listeners {
_ = l.Close()
}
s.logger.Debug(ctx, "closing all active connections", slog.F("count", len(s.conns)))
for c := range s.conns {
_ = c.Close()
}
// Close the underlying SSH server.
for p := range s.processes {
_ = cmdCancel(s.logger, p)
}
s.logger.Debug(ctx, "closing SSH server")
err := s.srv.Close()
s.mu.Unlock()
s.logger.Debug(ctx, "waiting for all goroutines to exit")
s.wg.Wait() // Wait for all goroutines to exit.
s.mu.Lock()
@@ -995,15 +1144,35 @@ func (s *Server) Close() error {
s.closing = nil
s.mu.Unlock()
s.logger.Debug(ctx, "closing server done")
return err
}
// Shutdown gracefully closes all active SSH connections and stops
// accepting new connections.
//
// Shutdown is not implemented.
func (*Server) Shutdown(_ context.Context) error {
// TODO(mafredri): Implement shutdown, SIGHUP running commands, etc.
// Shutdown stops accepting new connections. The current implementation
// calls Close() for simplicity instead of waiting for existing
// connections to close. If the context times out, Shutdown will return
// but Close() may not have completed.
func (s *Server) Shutdown(ctx context.Context) error {
ch := make(chan error, 1)
go func() {
// TODO(mafredri): Implement shutdown, SIGHUP running commands, etc.
// For now we just close the server.
ch <- s.Close()
}()
var err error
select {
case <-ctx.Done():
err = ctx.Err()
case err = <-ch:
}
// Re-check for context cancellation precedence.
if ctx.Err() != nil {
err = ctx.Err()
}
if err != nil {
return xerrors.Errorf("close server: %w", err)
}
return nil
}
@@ -1120,75 +1289,7 @@ func CoderSigner(seed int64) (gossh.Signer, error) {
// Clients should ignore the host key when connecting.
// The agent needs to authenticate with coderd to SSH,
// so SSH authentication doesn't improve security.
// Since the standard lib purposefully does not generate
// deterministic rsa keys, we need to do it ourselves.
coderHostKey := func() *rsa.PrivateKey {
// Create deterministic random source
// nolint: gosec
deterministicRand := rand.New(rand.NewSource(seed))
// Use fixed values for p and q based on the seed
p := big.NewInt(0)
q := big.NewInt(0)
e := big.NewInt(65537) // Standard RSA public exponent
// Generate deterministic primes using the seeded random
// Each prime should be ~1024 bits to get a 2048-bit key
for {
p.SetBit(p, 1024, 1) // Ensure it's large enough
for i := 0; i < 1024; i++ {
if deterministicRand.Int63()%2 == 1 {
p.SetBit(p, i, 1)
} else {
p.SetBit(p, i, 0)
}
}
if p.ProbablyPrime(20) {
break
}
}
for {
q.SetBit(q, 1024, 1) // Ensure it's large enough
for i := 0; i < 1024; i++ {
if deterministicRand.Int63()%2 == 1 {
q.SetBit(q, i, 1)
} else {
q.SetBit(q, i, 0)
}
}
if q.ProbablyPrime(20) && p.Cmp(q) != 0 {
break
}
}
// Calculate n = p * q
n := new(big.Int).Mul(p, q)
// Calculate phi = (p-1) * (q-1)
p1 := new(big.Int).Sub(p, big.NewInt(1))
q1 := new(big.Int).Sub(q, big.NewInt(1))
phi := new(big.Int).Mul(p1, q1)
// Calculate private exponent d
d := new(big.Int).ModInverse(e, phi)
// Create the private key
privateKey := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: n,
E: int(e.Int64()),
},
D: d,
Primes: []*big.Int{p, q},
}
// Compute precomputed values
privateKey.Precompute()
return privateKey
}()
coderHostKey := agentrsa.GenerateDeterministicKey(seed)
coderSigner, err := gossh.NewSignerFromKey(coderHostKey)
return coderSigner, err
+108 -44
View File
@@ -13,6 +13,7 @@ import (
"strings"
"sync"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/spf13/afero"
@@ -21,6 +22,7 @@ import (
"go.uber.org/goleak"
"golang.org/x/crypto/ssh"
"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/agent/agentexec"
@@ -124,7 +126,7 @@ type fakeEnvInfoer struct {
UserShellFn func(string) (string, error)
}
func (f *fakeEnvInfoer) CurrentUser() (u *user.User, err error) {
func (f *fakeEnvInfoer) User() (u *user.User, err error) {
return f.CurrentUserFn()
}
@@ -132,62 +134,124 @@ func (f *fakeEnvInfoer) Environ() []string {
return f.EnvironFn()
}
func (f *fakeEnvInfoer) UserHomeDir() (string, error) {
func (f *fakeEnvInfoer) HomeDir() (string, error) {
return f.UserHomeDirFn()
}
func (f *fakeEnvInfoer) UserShell(u string) (string, error) {
func (f *fakeEnvInfoer) Shell(u string) (string, error) {
return f.UserShellFn(u)
}
func (*fakeEnvInfoer) ModifyCommand(cmd string, args ...string) (string, []string) {
return cmd, args
}
func TestNewServer_CloseActiveConnections(t *testing.T) {
t.Parallel()
ctx := context.Background()
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true})
s, err := agentssh.NewServer(ctx, logger, prometheus.NewRegistry(), afero.NewMemMapFs(), agentexec.DefaultExecer, nil)
require.NoError(t, err)
defer s.Close()
err = s.UpdateHostSigner(42)
assert.NoError(t, err)
ln, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
err := s.Serve(ln)
assert.Error(t, err) // Server is closed.
}()
pty := ptytest.New(t)
doClose := make(chan struct{})
go func() {
defer wg.Done()
c := sshClient(t, ln.Addr().String())
sess, err := c.NewSession()
assert.NoError(t, err)
sess.Stdin = pty.Input()
sess.Stdout = pty.Output()
sess.Stderr = pty.Output()
assert.NoError(t, err)
err = sess.Start("")
prepare := func(ctx context.Context, t *testing.T) (*agentssh.Server, func()) {
t.Helper()
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
s, err := agentssh.NewServer(ctx, logger, prometheus.NewRegistry(), afero.NewMemMapFs(), agentexec.DefaultExecer, nil)
require.NoError(t, err)
t.Cleanup(func() {
_ = s.Close()
})
err = s.UpdateHostSigner(42)
assert.NoError(t, err)
close(doClose)
err = sess.Wait()
assert.Error(t, err)
}()
ln, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
<-doClose
err = s.Close()
require.NoError(t, err)
waitConns := make([]chan struct{}, 4)
wg.Wait()
var wg sync.WaitGroup
wg.Add(1 + len(waitConns))
go func() {
defer wg.Done()
err := s.Serve(ln)
assert.Error(t, err) // Server is closed.
}()
for i := 0; i < len(waitConns); i++ {
waitConns[i] = make(chan struct{})
go func(ch chan struct{}) {
defer wg.Done()
c := sshClient(t, ln.Addr().String())
sess, err := c.NewSession()
assert.NoError(t, err)
pty := ptytest.New(t)
sess.Stdin = pty.Input()
sess.Stdout = pty.Output()
sess.Stderr = pty.Output()
// Every other session will request a PTY.
if i%2 == 0 {
err = sess.RequestPty("xterm", 80, 80, nil)
assert.NoError(t, err)
}
// The 60 seconds here is intended to be longer than the
// test. The shutdown should propagate.
if runtime.GOOS == "windows" {
// Best effort to at least partially test this in Windows.
err = sess.Start("echo start\"ed\" && sleep 60")
} else {
err = sess.Start("/bin/bash -c 'trap \"sleep 60\" SIGTERM; echo start\"ed\"; sleep 60'")
}
assert.NoError(t, err)
// Allow the session to settle (i.e. reach echo).
pty.ExpectMatchContext(ctx, "started")
// Sleep a bit to ensure the sleep has started.
time.Sleep(testutil.IntervalMedium)
close(ch)
err = sess.Wait()
assert.Error(t, err)
}(waitConns[i])
}
for _, ch := range waitConns {
select {
case <-ctx.Done():
t.Fatal("timeout")
case <-ch:
}
}
return s, wg.Wait
}
t.Run("Close", func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t, testutil.WaitMedium)
s, wait := prepare(ctx, t)
err := s.Close()
require.NoError(t, err)
wait()
})
t.Run("Shutdown", func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t, testutil.WaitMedium)
s, wait := prepare(ctx, t)
err := s.Shutdown(ctx)
require.NoError(t, err)
wait()
})
t.Run("Shutdown Early", func(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t, testutil.WaitMedium)
s, wait := prepare(ctx, t)
ctx, cancel := context.WithCancel(ctx)
cancel()
err := s.Shutdown(ctx)
require.ErrorIs(t, err, context.Canceled)
wait()
})
}
func TestNewServer_Signal(t *testing.T) {
+22
View File
@@ -0,0 +1,22 @@
//go:build !windows
package agentssh
import (
"context"
"os"
"syscall"
"cdr.dev/slog"
)
func cmdSysProcAttr() *syscall.SysProcAttr {
return &syscall.SysProcAttr{
Setsid: true,
}
}
func cmdCancel(logger slog.Logger, p *os.Process) error {
logger.Debug(context.Background(), "cmdCancel: sending SIGHUP to process and children", slog.F("pid", p.Pid))
return syscall.Kill(-p.Pid, syscall.SIGHUP)
}
+23
View File
@@ -0,0 +1,23 @@
package agentssh
import (
"context"
"os"
"syscall"
"cdr.dev/slog"
)
func cmdSysProcAttr() *syscall.SysProcAttr {
return &syscall.SysProcAttr{}
}
func cmdCancel(logger slog.Logger, p *os.Process) error {
logger.Debug(context.Background(), "cmdCancel: killing process", slog.F("pid", p.Pid))
// Windows doesn't support sending signals to process groups, so we
// have to kill the process directly. In the future, we may want to
// implement a more sophisticated solution for process groups on
// Windows, but for now, this is a simple way to ensure that the
// process is terminated when the context is cancelled.
return p.Kill()
}
+10 -1
View File
@@ -6,6 +6,7 @@ import (
"sync"
"github.com/gliderlabs/ssh"
"github.com/google/uuid"
"go.uber.org/atomic"
gossh "golang.org/x/crypto/ssh"
@@ -28,9 +29,11 @@ type JetbrainsChannelWatcher struct {
gossh.NewChannel
jetbrainsCounter *atomic.Int64
logger slog.Logger
originAddr string
reportConnection reportConnectionFunc
}
func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel gossh.NewChannel, counter *atomic.Int64) gossh.NewChannel {
func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, reportConnection reportConnectionFunc, newChannel gossh.NewChannel, counter *atomic.Int64) gossh.NewChannel {
d := localForwardChannelData{}
if err := gossh.Unmarshal(newChannel.ExtraData(), &d); err != nil {
// If the data fails to unmarshal, do nothing.
@@ -61,12 +64,17 @@ func NewJetbrainsChannelWatcher(ctx ssh.Context, logger slog.Logger, newChannel
NewChannel: newChannel,
jetbrainsCounter: counter,
logger: logger.With(slog.F("destination_port", d.DestPort)),
originAddr: d.OriginAddr,
reportConnection: reportConnection,
}
}
func (w *JetbrainsChannelWatcher) Accept() (gossh.Channel, <-chan *gossh.Request, error) {
disconnected := w.reportConnection(uuid.New(), MagicSessionTypeJetBrains, w.originAddr)
c, r, err := w.NewChannel.Accept()
if err != nil {
disconnected(1, err.Error())
return c, r, err
}
w.jetbrainsCounter.Add(1)
@@ -77,6 +85,7 @@ func (w *JetbrainsChannelWatcher) Accept() (gossh.Channel, <-chan *gossh.Request
Channel: c,
done: func() {
w.jetbrainsCounter.Add(-1)
disconnected(0, "")
// nolint: gocritic // JetBrains is a proper noun and should be capitalized
w.logger.Debug(context.Background(), "JetBrains watcher channel closed")
},
+6 -1
View File
@@ -116,7 +116,8 @@ func (s *Server) x11Handler(ctx ssh.Context, x11 ssh.X11) (displayNumber int, ha
OriginatorPort uint32
}{
OriginatorAddress: tcpAddr.IP.String(),
OriginatorPort: uint32(tcpAddr.Port),
// #nosec G115 - Safe conversion as TCP port numbers are within uint32 range (0-65535)
OriginatorPort: uint32(tcpAddr.Port),
}))
if err != nil {
s.logger.Warn(ctx, "failed to open X11 channel", slog.Error(err))
@@ -294,6 +295,7 @@ func addXauthEntry(ctx context.Context, fs afero.Fs, host string, display string
return xerrors.Errorf("failed to write family: %w", err)
}
// #nosec G115 - Safe conversion for host name length which is expected to be within uint16 range
err = binary.Write(file, binary.BigEndian, uint16(len(host)))
if err != nil {
return xerrors.Errorf("failed to write host length: %w", err)
@@ -303,6 +305,7 @@ func addXauthEntry(ctx context.Context, fs afero.Fs, host string, display string
return xerrors.Errorf("failed to write host: %w", err)
}
// #nosec G115 - Safe conversion for display name length which is expected to be within uint16 range
err = binary.Write(file, binary.BigEndian, uint16(len(display)))
if err != nil {
return xerrors.Errorf("failed to write display length: %w", err)
@@ -312,6 +315,7 @@ func addXauthEntry(ctx context.Context, fs afero.Fs, host string, display string
return xerrors.Errorf("failed to write display: %w", err)
}
// #nosec G115 - Safe conversion for auth protocol length which is expected to be within uint16 range
err = binary.Write(file, binary.BigEndian, uint16(len(authProtocol)))
if err != nil {
return xerrors.Errorf("failed to write auth protocol length: %w", err)
@@ -321,6 +325,7 @@ func addXauthEntry(ctx context.Context, fs afero.Fs, host string, display string
return xerrors.Errorf("failed to write auth protocol: %w", err)
}
// #nosec G115 - Safe conversion for auth cookie length which is expected to be within uint16 range
err = binary.Write(file, binary.BigEndian, uint16(len(authCookieBytes)))
if err != nil {
return xerrors.Errorf("failed to write auth cookie length: %w", err)
+25 -14
View File
@@ -3,6 +3,7 @@ package agenttest
import (
"context"
"io"
"slices"
"sync"
"sync/atomic"
"testing"
@@ -12,7 +13,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/emptypb"
@@ -24,7 +24,7 @@ import (
agentproto "github.com/coder/coder/v2/agent/proto"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk"
drpcsdk "github.com/coder/coder/v2/codersdk/drpc"
"github.com/coder/coder/v2/codersdk/drpcsdk"
"github.com/coder/coder/v2/tailnet"
"github.com/coder/coder/v2/tailnet/proto"
"github.com/coder/coder/v2/testutil"
@@ -60,6 +60,7 @@ func NewClient(t testing.TB,
err = agentproto.DRPCRegisterAgent(mux, fakeAAPI)
require.NoError(t, err)
server := drpcserver.NewWithOptions(mux, drpcserver.Options{
Manager: drpcsdk.DefaultDRPCOptions(nil),
Log: func(err error) {
if xerrors.Is(err, io.EOF) {
return
@@ -97,8 +98,8 @@ func (c *Client) Close() {
c.derpMapOnce.Do(func() { close(c.derpMapUpdates) })
}
func (c *Client) ConnectRPC24(ctx context.Context) (
agentproto.DRPCAgentClient24, proto.DRPCTailnetClient24, error,
func (c *Client) ConnectRPC25(ctx context.Context) (
agentproto.DRPCAgentClient25, proto.DRPCTailnetClient25, error,
) {
conn, lis := drpcsdk.MemTransportPipe()
c.LastWorkspaceAgent = func() {
@@ -158,20 +159,24 @@ func (c *Client) SetLogsChannel(ch chan<- *agentproto.BatchCreateLogsRequest) {
c.fakeAgentAPI.SetLogsChannel(ch)
}
func (c *Client) GetConnectionReports() []*agentproto.ReportConnectionRequest {
return c.fakeAgentAPI.GetConnectionReports()
}
type FakeAgentAPI struct {
sync.Mutex
t testing.TB
logger slog.Logger
manifest *agentproto.Manifest
startupCh chan *agentproto.Startup
statsCh chan *agentproto.Stats
appHealthCh chan *agentproto.BatchUpdateAppHealthRequest
logsCh chan<- *agentproto.BatchCreateLogsRequest
lifecycleStates []codersdk.WorkspaceAgentLifecycle
metadata map[string]agentsdk.Metadata
timings []*agentproto.Timing
connections []*agentproto.Connection
manifest *agentproto.Manifest
startupCh chan *agentproto.Startup
statsCh chan *agentproto.Stats
appHealthCh chan *agentproto.BatchUpdateAppHealthRequest
logsCh chan<- *agentproto.BatchCreateLogsRequest
lifecycleStates []codersdk.WorkspaceAgentLifecycle
metadata map[string]agentsdk.Metadata
timings []*agentproto.Timing
connectionReports []*agentproto.ReportConnectionRequest
getAnnouncementBannersFunc func() ([]codersdk.BannerConfig, error)
getResourcesMonitoringConfigurationFunc func() (*agentproto.GetResourcesMonitoringConfigurationResponse, error)
@@ -348,12 +353,18 @@ func (f *FakeAgentAPI) ScriptCompleted(_ context.Context, req *agentproto.Worksp
func (f *FakeAgentAPI) ReportConnection(_ context.Context, req *agentproto.ReportConnectionRequest) (*emptypb.Empty, error) {
f.Lock()
f.connections = append(f.connections, req.GetConnection())
f.connectionReports = append(f.connectionReports, req)
f.Unlock()
return &emptypb.Empty{}, nil
}
func (f *FakeAgentAPI) GetConnectionReports() []*agentproto.ReportConnectionRequest {
f.Lock()
defer f.Unlock()
return slices.Clone(f.connectionReports)
}
func NewFakeAgentAPI(t testing.TB, logger slog.Logger, manifest *agentproto.Manifest, statsCh chan *agentproto.Stats) *FakeAgentAPI {
return &FakeAgentAPI{
t: t,
+42 -4
View File
@@ -7,12 +7,14 @@ import (
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"github.com/coder/coder/v2/agent/agentcontainers"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk"
)
func (a *agent) apiHandler() http.Handler {
func (a *agent) apiHandler() (http.Handler, func() error) {
r := chi.NewRouter()
r.Get("/", func(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.Response{
@@ -36,18 +38,54 @@ func (a *agent) apiHandler() http.Handler {
ignorePorts: cpy,
cacheDuration: cacheDuration,
}
ch := agentcontainers.New(agentcontainers.WithLister(a.lister))
if a.experimentalDevcontainersEnabled {
containerAPIOpts := []agentcontainers.Option{
agentcontainers.WithExecer(a.execer),
agentcontainers.WithScriptLogger(func(logSourceID uuid.UUID) agentcontainers.ScriptLogger {
return a.logSender.GetScriptLogger(logSourceID)
}),
}
manifest := a.manifest.Load()
if manifest != nil && len(manifest.Devcontainers) > 0 {
containerAPIOpts = append(
containerAPIOpts,
agentcontainers.WithDevcontainers(manifest.Devcontainers, manifest.Scripts),
)
}
// Append after to allow the agent options to override the default options.
containerAPIOpts = append(containerAPIOpts, a.containerAPIOptions...)
containerAPI := agentcontainers.NewAPI(a.logger.Named("containers"), containerAPIOpts...)
r.Mount("/api/v0/containers", containerAPI.Routes())
a.containerAPI.Store(containerAPI)
} else {
r.HandleFunc("/api/v0/containers", func(w http.ResponseWriter, r *http.Request) {
httpapi.Write(r.Context(), w, http.StatusForbidden, codersdk.Response{
Message: "The agent dev containers feature is experimental and not enabled by default.",
Detail: "To enable this feature, set CODER_AGENT_DEVCONTAINERS_ENABLE=true in your template.",
})
})
}
promHandler := PrometheusMetricsHandler(a.prometheusRegistry, a.logger)
r.Get("/api/v0/containers", ch.ServeHTTP)
r.Get("/api/v0/listening-ports", lp.handler)
r.Get("/api/v0/netcheck", a.HandleNetcheck)
r.Post("/api/v0/list-directory", a.HandleLS)
r.Get("/debug/logs", a.HandleHTTPDebugLogs)
r.Get("/debug/magicsock", a.HandleHTTPDebugMagicsock)
r.Get("/debug/magicsock/debug-logging/{state}", a.HandleHTTPMagicsockDebugLoggingState)
r.Get("/debug/manifest", a.HandleHTTPDebugManifest)
r.Get("/debug/prometheus", promHandler.ServeHTTP)
return r
return r, func() error {
if containerAPI := a.containerAPI.Load(); containerAPI != nil {
return containerAPI.Close()
}
return nil
}
}
type listeningPortsHandler struct {
+2 -2
View File
@@ -167,8 +167,8 @@ func shouldStartTicker(app codersdk.WorkspaceApp) bool {
return app.Healthcheck.URL != "" && app.Healthcheck.Interval > 0 && app.Healthcheck.Threshold > 0
}
func healthChanged(old map[uuid.UUID]codersdk.WorkspaceAppHealth, new map[uuid.UUID]codersdk.WorkspaceAppHealth) bool {
for name, newValue := range new {
func healthChanged(old map[uuid.UUID]codersdk.WorkspaceAppHealth, updated map[uuid.UUID]codersdk.WorkspaceAppHealth) bool {
for name, newValue := range updated {
oldValue, found := old[name]
if !found {
return true
+13 -13
View File
@@ -78,7 +78,7 @@ func TestAppHealth_Healthy(t *testing.T) {
healthchecksStarted := make([]string, 2)
for i := 0; i < 2; i++ {
c := healthcheckTrap.MustWait(ctx)
c.Release()
c.MustRelease(ctx)
healthchecksStarted[i] = c.Tags[1]
}
slices.Sort(healthchecksStarted)
@@ -87,12 +87,12 @@ func TestAppHealth_Healthy(t *testing.T) {
// advance the clock 1ms before the report ticker starts, so that it's not
// simultaneous with the checks.
mClock.Advance(time.Millisecond).MustWait(ctx)
reportTrap.MustWait(ctx).Release()
reportTrap.MustWait(ctx).MustRelease(ctx)
mClock.Advance(999 * time.Millisecond).MustWait(ctx) // app2 is now healthy
mClock.Advance(time.Millisecond).MustWait(ctx) // report gets triggered
update := testutil.RequireRecvCtx(ctx, t, fakeAPI.AppHealthCh())
update := testutil.TryReceive(ctx, t, fakeAPI.AppHealthCh())
require.Len(t, update.GetUpdates(), 2)
applyUpdate(t, apps, update)
require.Equal(t, codersdk.WorkspaceAppHealthHealthy, apps[1].Health)
@@ -101,7 +101,7 @@ func TestAppHealth_Healthy(t *testing.T) {
mClock.Advance(999 * time.Millisecond).MustWait(ctx) // app3 is now healthy
mClock.Advance(time.Millisecond).MustWait(ctx) // report gets triggered
update = testutil.RequireRecvCtx(ctx, t, fakeAPI.AppHealthCh())
update = testutil.TryReceive(ctx, t, fakeAPI.AppHealthCh())
require.Len(t, update.GetUpdates(), 2)
applyUpdate(t, apps, update)
require.Equal(t, codersdk.WorkspaceAppHealthHealthy, apps[1].Health)
@@ -143,11 +143,11 @@ func TestAppHealth_500(t *testing.T) {
fakeAPI, closeFn := setupAppReporter(ctx, t, slices.Clone(apps), handlers, mClock)
defer closeFn()
healthcheckTrap.MustWait(ctx).Release()
healthcheckTrap.MustWait(ctx).MustRelease(ctx)
// advance the clock 1ms before the report ticker starts, so that it's not
// simultaneous with the checks.
mClock.Advance(time.Millisecond).MustWait(ctx)
reportTrap.MustWait(ctx).Release()
reportTrap.MustWait(ctx).MustRelease(ctx)
mClock.Advance(999 * time.Millisecond).MustWait(ctx) // check gets triggered
mClock.Advance(time.Millisecond).MustWait(ctx) // report gets triggered, but unsent since we are at the threshold
@@ -155,7 +155,7 @@ func TestAppHealth_500(t *testing.T) {
mClock.Advance(999 * time.Millisecond).MustWait(ctx) // 2nd check, crosses threshold
mClock.Advance(time.Millisecond).MustWait(ctx) // 2nd report, sends update
update := testutil.RequireRecvCtx(ctx, t, fakeAPI.AppHealthCh())
update := testutil.TryReceive(ctx, t, fakeAPI.AppHealthCh())
require.Len(t, update.GetUpdates(), 1)
applyUpdate(t, apps, update)
require.Equal(t, codersdk.WorkspaceAppHealthUnhealthy, apps[0].Health)
@@ -202,28 +202,28 @@ func TestAppHealth_Timeout(t *testing.T) {
fakeAPI, closeFn := setupAppReporter(ctx, t, apps, handlers, mClock)
defer closeFn()
healthcheckTrap.MustWait(ctx).Release()
healthcheckTrap.MustWait(ctx).MustRelease(ctx)
// advance the clock 1ms before the report ticker starts, so that it's not
// simultaneous with the checks.
mClock.Set(ms(1)).MustWait(ctx)
reportTrap.MustWait(ctx).Release()
reportTrap.MustWait(ctx).MustRelease(ctx)
w := mClock.Set(ms(1000)) // 1st check starts
timeoutTrap.MustWait(ctx).Release()
timeoutTrap.MustWait(ctx).MustRelease(ctx)
mClock.Set(ms(1001)).MustWait(ctx) // report tick, no change
mClock.Set(ms(1999)) // timeout pops
w.MustWait(ctx) // 1st check finished
w = mClock.Set(ms(2000)) // 2nd check starts
timeoutTrap.MustWait(ctx).Release()
timeoutTrap.MustWait(ctx).MustRelease(ctx)
mClock.Set(ms(2001)).MustWait(ctx) // report tick, no change
mClock.Set(ms(2999)) // timeout pops
w.MustWait(ctx) // 2nd check finished
// app is now unhealthy after 2 timeouts
mClock.Set(ms(3000)) // 3rd check starts
timeoutTrap.MustWait(ctx).Release()
timeoutTrap.MustWait(ctx).MustRelease(ctx)
mClock.Set(ms(3001)).MustWait(ctx) // report tick, sends changes
update := testutil.RequireRecvCtx(ctx, t, fakeAPI.AppHealthCh())
update := testutil.TryReceive(ctx, t, fakeAPI.AppHealthCh())
require.Len(t, update.GetUpdates(), 1)
applyUpdate(t, apps, update)
require.Equal(t, codersdk.WorkspaceAppHealthUnhealthy, apps[0].Health)
+1 -1
View File
@@ -44,6 +44,6 @@ func TestCheckpoint_WaitComplete(t *testing.T) {
errCh <- uut.wait(ctx)
}()
uut.complete(err)
got := testutil.RequireRecvCtx(ctx, t, errCh)
got := testutil.TryReceive(ctx, t, errCh)
require.Equal(t, err, got)
}
+198
View File
@@ -0,0 +1,198 @@
package agent
import (
"errors"
"net/http"
"os"
"path/filepath"
"regexp"
"runtime"
"slices"
"strings"
"github.com/shirou/gopsutil/v4/disk"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk"
)
var WindowsDriveRegex = regexp.MustCompile(`^[a-zA-Z]:\\$`)
func (*agent) HandleLS(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var query LSRequest
if !httpapi.Read(ctx, rw, r, &query) {
return
}
resp, err := listFiles(query)
if err != nil {
status := http.StatusInternalServerError
switch {
case errors.Is(err, os.ErrNotExist):
status = http.StatusNotFound
case errors.Is(err, os.ErrPermission):
status = http.StatusForbidden
default:
}
httpapi.Write(ctx, rw, status, codersdk.Response{
Message: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusOK, resp)
}
func listFiles(query LSRequest) (LSResponse, error) {
var fullPath []string
switch query.Relativity {
case LSRelativityHome:
home, err := os.UserHomeDir()
if err != nil {
return LSResponse{}, xerrors.Errorf("failed to get user home directory: %w", err)
}
fullPath = []string{home}
case LSRelativityRoot:
if runtime.GOOS == "windows" {
if len(query.Path) == 0 {
return listDrives()
}
if !WindowsDriveRegex.MatchString(query.Path[0]) {
return LSResponse{}, xerrors.Errorf("invalid drive letter %q", query.Path[0])
}
} else {
fullPath = []string{"/"}
}
default:
return LSResponse{}, xerrors.Errorf("unsupported relativity type %q", query.Relativity)
}
fullPath = append(fullPath, query.Path...)
fullPathRelative := filepath.Join(fullPath...)
absolutePathString, err := filepath.Abs(fullPathRelative)
if err != nil {
return LSResponse{}, xerrors.Errorf("failed to get absolute path of %q: %w", fullPathRelative, err)
}
// codeql[go/path-injection] - The intent is to allow the user to navigate to any directory in their workspace.
f, err := os.Open(absolutePathString)
if err != nil {
return LSResponse{}, xerrors.Errorf("failed to open directory %q: %w", absolutePathString, err)
}
defer f.Close()
stat, err := f.Stat()
if err != nil {
return LSResponse{}, xerrors.Errorf("failed to stat directory %q: %w", absolutePathString, err)
}
if !stat.IsDir() {
return LSResponse{}, xerrors.Errorf("path %q is not a directory", absolutePathString)
}
// `contents` may be partially populated even if the operation fails midway.
contents, _ := f.ReadDir(-1)
respContents := make([]LSFile, 0, len(contents))
for _, file := range contents {
respContents = append(respContents, LSFile{
Name: file.Name(),
AbsolutePathString: filepath.Join(absolutePathString, file.Name()),
IsDir: file.IsDir(),
})
}
// Sort alphabetically: directories then files
slices.SortFunc(respContents, func(a, b LSFile) int {
if a.IsDir && !b.IsDir {
return -1
}
if !a.IsDir && b.IsDir {
return 1
}
return strings.Compare(a.Name, b.Name)
})
absolutePath := pathToArray(absolutePathString)
return LSResponse{
AbsolutePath: absolutePath,
AbsolutePathString: absolutePathString,
Contents: respContents,
}, nil
}
func listDrives() (LSResponse, error) {
// disk.Partitions() will return partitions even if there was a failure to
// get one. Any errored partitions will not be returned.
partitionStats, err := disk.Partitions(true)
if err != nil && len(partitionStats) == 0 {
// Only return the error if there were no partitions returned.
return LSResponse{}, xerrors.Errorf("failed to get partitions: %w", err)
}
contents := make([]LSFile, 0, len(partitionStats))
for _, a := range partitionStats {
// Drive letters on Windows have a trailing separator as part of their name.
// i.e. `os.Open("C:")` does not work, but `os.Open("C:\\")` does.
name := a.Mountpoint + string(os.PathSeparator)
contents = append(contents, LSFile{
Name: name,
AbsolutePathString: name,
IsDir: true,
})
}
return LSResponse{
AbsolutePath: []string{},
AbsolutePathString: "",
Contents: contents,
}, nil
}
func pathToArray(path string) []string {
out := strings.FieldsFunc(path, func(r rune) bool {
return r == os.PathSeparator
})
// Drive letters on Windows have a trailing separator as part of their name.
// i.e. `os.Open("C:")` does not work, but `os.Open("C:\\")` does.
if runtime.GOOS == "windows" && len(out) > 0 {
out[0] += string(os.PathSeparator)
}
return out
}
type LSRequest struct {
// e.g. [], ["repos", "coder"],
Path []string `json:"path"`
// Whether the supplied path is relative to the user's home directory,
// or the root directory.
Relativity LSRelativity `json:"relativity"`
}
type LSResponse struct {
AbsolutePath []string `json:"absolute_path"`
// Returned so clients can display the full path to the user, and
// copy it to configure file sync
// e.g. Windows: "C:\\Users\\coder"
// Linux: "/home/coder"
AbsolutePathString string `json:"absolute_path_string"`
Contents []LSFile `json:"contents"`
}
type LSFile struct {
Name string `json:"name"`
// e.g. "C:\\Users\\coder\\hello.txt"
// "/home/coder/hello.txt"
AbsolutePathString string `json:"absolute_path_string"`
IsDir bool `json:"is_dir"`
}
type LSRelativity string
const (
LSRelativityRoot LSRelativity = "root"
LSRelativityHome LSRelativity = "home"
)
+208
View File
@@ -0,0 +1,208 @@
package agent
import (
"os"
"path/filepath"
"runtime"
"testing"
"github.com/stretchr/testify/require"
)
func TestListFilesNonExistentDirectory(t *testing.T) {
t.Parallel()
query := LSRequest{
Path: []string{"idontexist"},
Relativity: LSRelativityHome,
}
_, err := listFiles(query)
require.ErrorIs(t, err, os.ErrNotExist)
}
func TestListFilesPermissionDenied(t *testing.T) {
t.Parallel()
if runtime.GOOS == "windows" {
t.Skip("creating an unreadable-by-user directory is non-trivial on Windows")
}
home, err := os.UserHomeDir()
require.NoError(t, err)
tmpDir := t.TempDir()
reposDir := filepath.Join(tmpDir, "repos")
err = os.Mkdir(reposDir, 0o000)
require.NoError(t, err)
rel, err := filepath.Rel(home, reposDir)
require.NoError(t, err)
query := LSRequest{
Path: pathToArray(rel),
Relativity: LSRelativityHome,
}
_, err = listFiles(query)
require.ErrorIs(t, err, os.ErrPermission)
}
func TestListFilesNotADirectory(t *testing.T) {
t.Parallel()
home, err := os.UserHomeDir()
require.NoError(t, err)
tmpDir := t.TempDir()
filePath := filepath.Join(tmpDir, "file.txt")
err = os.WriteFile(filePath, []byte("content"), 0o600)
require.NoError(t, err)
rel, err := filepath.Rel(home, filePath)
require.NoError(t, err)
query := LSRequest{
Path: pathToArray(rel),
Relativity: LSRelativityHome,
}
_, err = listFiles(query)
require.ErrorContains(t, err, "is not a directory")
}
func TestListFilesSuccess(t *testing.T) {
t.Parallel()
tc := []struct {
name string
baseFunc func(t *testing.T) string
relativity LSRelativity
}{
{
name: "home",
baseFunc: func(t *testing.T) string {
home, err := os.UserHomeDir()
require.NoError(t, err)
return home
},
relativity: LSRelativityHome,
},
{
name: "root",
baseFunc: func(*testing.T) string {
if runtime.GOOS == "windows" {
return ""
}
return "/"
},
relativity: LSRelativityRoot,
},
}
// nolint:paralleltest // Not since Go v1.22.
for _, tc := range tc {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
base := tc.baseFunc(t)
tmpDir := t.TempDir()
reposDir := filepath.Join(tmpDir, "repos")
err := os.Mkdir(reposDir, 0o755)
require.NoError(t, err)
downloadsDir := filepath.Join(tmpDir, "Downloads")
err = os.Mkdir(downloadsDir, 0o755)
require.NoError(t, err)
textFile := filepath.Join(tmpDir, "file.txt")
err = os.WriteFile(textFile, []byte("content"), 0o600)
require.NoError(t, err)
var queryComponents []string
// We can't get an absolute path relative to empty string on Windows.
if runtime.GOOS == "windows" && base == "" {
queryComponents = pathToArray(tmpDir)
} else {
rel, err := filepath.Rel(base, tmpDir)
require.NoError(t, err)
queryComponents = pathToArray(rel)
}
query := LSRequest{
Path: queryComponents,
Relativity: tc.relativity,
}
resp, err := listFiles(query)
require.NoError(t, err)
require.Equal(t, tmpDir, resp.AbsolutePathString)
// Output is sorted
require.Equal(t, []LSFile{
{
Name: "Downloads",
AbsolutePathString: downloadsDir,
IsDir: true,
},
{
Name: "repos",
AbsolutePathString: reposDir,
IsDir: true,
},
{
Name: "file.txt",
AbsolutePathString: textFile,
IsDir: false,
},
}, resp.Contents)
})
}
}
func TestListFilesListDrives(t *testing.T) {
t.Parallel()
if runtime.GOOS != "windows" {
t.Skip("skipping test on non-Windows OS")
}
query := LSRequest{
Path: []string{},
Relativity: LSRelativityRoot,
}
resp, err := listFiles(query)
require.NoError(t, err)
require.Contains(t, resp.Contents, LSFile{
Name: "C:\\",
AbsolutePathString: "C:\\",
IsDir: true,
})
query = LSRequest{
Path: []string{"C:\\"},
Relativity: LSRelativityRoot,
}
resp, err = listFiles(query)
require.NoError(t, err)
query = LSRequest{
Path: resp.AbsolutePath,
Relativity: LSRelativityRoot,
}
resp, err = listFiles(query)
require.NoError(t, err)
// System directory should always exist
require.Contains(t, resp.Contents, LSFile{
Name: "Windows",
AbsolutePathString: "C:\\Windows",
IsDir: true,
})
query = LSRequest{
// Network drives are not supported.
Path: []string{"\\sshfs\\work"},
Relativity: LSRelativityRoot,
}
resp, err = listFiles(query)
require.ErrorContains(t, err, "drive")
}
+4 -3
View File
@@ -89,21 +89,22 @@ func (a *agent) collectMetrics(ctx context.Context) []*proto.Stats_Metric {
for _, metric := range metricFamily.GetMetric() {
labels := toAgentMetricLabels(metric.Label)
if metric.Counter != nil {
switch {
case metric.Counter != nil:
collected = append(collected, &proto.Stats_Metric{
Name: metricFamily.GetName(),
Type: proto.Stats_Metric_COUNTER,
Value: metric.Counter.GetValue(),
Labels: labels,
})
} else if metric.Gauge != nil {
case metric.Gauge != nil:
collected = append(collected, &proto.Stats_Metric{
Name: metricFamily.GetName(),
Type: proto.Stats_Metric_GAUGE,
Value: metric.Gauge.GetValue(),
Labels: labels,
})
} else {
default:
a.logger.Error(ctx, "unsupported metric type", slog.F("type", metricFamily.Type.String()))
}
}

Some files were not shown because too many files have changed in this diff Show More