Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Cherry-pick for release 2.25#19169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
stirby merged 7 commits intorelease/2.25fromcherries/2.25
Aug 5, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions.github/workflows/ci.yaml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,6 +340,11 @@ jobs:
- 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
Expand Down
4 changes: 2 additions & 2 deletions.github/workflows/release.yaml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand DownExpand Up@@ -655,7 +655,7 @@ jobs:
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
done

- name: Publish release
run: |
Expand Down
26 changes: 19 additions & 7 deletionsagent/agentcontainers/api.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -77,7 +77,8 @@ type API struct {
subAgentURL string
subAgentEnv []string

projectDiscovery bool // If we should perform project discovery or not.
projectDiscovery bool // If we should perform project discovery or not.
discoveryAutostart bool // If we should autostart discovered projects.

ownerName string
workspaceName string
Expand DownExpand Up@@ -144,7 +145,8 @@ func WithCommandEnv(ce CommandEnv) Option {
strings.HasPrefix(s, "CODER_AGENT_TOKEN=") ||
strings.HasPrefix(s, "CODER_AGENT_AUTH=") ||
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_ENABLE=") ||
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_PROJECT_DISCOVERY_ENABLE=")
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_PROJECT_DISCOVERY_ENABLE=") ||
strings.HasPrefix(s, "CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE=")
})
return shell, dir, env, nil
}
Expand DownExpand Up@@ -287,6 +289,14 @@ func WithProjectDiscovery(projectDiscovery bool) Option {
}
}

// WithDiscoveryAutostart sets if the API should attempt to autostart
// projects that have been discovered
func WithDiscoveryAutostart(discoveryAutostart bool) Option {
return func(api *API) {
api.discoveryAutostart = discoveryAutostart
}
}

// ScriptLogger is an interface for sending devcontainer logs to the
// controlplane.
type ScriptLogger interface {
Expand DownExpand Up@@ -542,11 +552,13 @@ func (api *API) discoverDevcontainersInProject(projectPath string) error {
Container: nil,
}

config, err := api.dccli.ReadConfig(api.ctx, workspaceFolder, path, []string{})
if err != nil {
logger.Error(api.ctx, "read project configuration", slog.Error(err))
} else if config.Configuration.Customizations.Coder.AutoStart {
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStarting
if api.discoveryAutostart {
config, err := api.dccli.ReadConfig(api.ctx, workspaceFolder, path, []string{})
if err != nil {
logger.Error(api.ctx, "read project configuration", slog.Error(err))
} else if config.Configuration.Customizations.Coder.AutoStart {
dc.Status = codersdk.WorkspaceAgentDevcontainerStatusStarting
}
}

api.knownDevcontainers[workspaceFolder] = dc
Expand Down
70 changes: 70 additions & 0 deletionsagent/agentcontainers/api_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -3792,6 +3792,7 @@ func TestDevcontainerDiscovery(t *testing.T) {
agentcontainers.WithContainerCLI(&fakeContainerCLI{}),
agentcontainers.WithDevcontainerCLI(mDCCLI),
agentcontainers.WithProjectDiscovery(true),
agentcontainers.WithDiscoveryAutostart(true),
)
api.Start()
defer api.Close()
Expand All@@ -3813,5 +3814,74 @@ func TestDevcontainerDiscovery(t *testing.T) {
// Then: We expect the mock infra to not fail.
})
}

t.Run("Disabled", func(t *testing.T) {
t.Parallel()
var (
ctx = testutil.Context(t, testutil.WaitShort)
logger = testutil.Logger(t)
mClock = quartz.NewMock(t)
mDCCLI = acmock.NewMockDevcontainerCLI(gomock.NewController(t))

fs = map[string]string{
"/home/coder/.git/HEAD": "",
"/home/coder/.devcontainer/devcontainer.json": "",
}

r = chi.NewRouter()
)

// We expect that neither `ReadConfig`, nor `Up` are called as we
// have explicitly disabled the agentcontainers API from attempting
// to autostart devcontainers that it discovers.
mDCCLI.EXPECT().ReadConfig(gomock.Any(),
"/home/coder",
"/home/coder/.devcontainer/devcontainer.json",
[]string{},
).Return(agentcontainers.DevcontainerConfig{
Configuration: agentcontainers.DevcontainerConfiguration{
Customizations: agentcontainers.DevcontainerCustomizations{
Coder: agentcontainers.CoderCustomization{
AutoStart: true,
},
},
},
}, nil).Times(0)

mDCCLI.EXPECT().Up(gomock.Any(),
"/home/coder",
"/home/coder/.devcontainer/devcontainer.json",
gomock.Any(),
).Return("", nil).Times(0)

api := agentcontainers.NewAPI(logger,
agentcontainers.WithClock(mClock),
agentcontainers.WithWatcher(watcher.NewNoop()),
agentcontainers.WithFileSystem(initFS(t, fs)),
agentcontainers.WithManifestInfo("owner", "workspace", "parent-agent", "/home/coder"),
agentcontainers.WithContainerCLI(&fakeContainerCLI{}),
agentcontainers.WithDevcontainerCLI(mDCCLI),
agentcontainers.WithProjectDiscovery(true),
agentcontainers.WithDiscoveryAutostart(false),
)
api.Start()
defer api.Close()
r.Mount("/", api.Routes())

// When: All expected dev containers have been found.
require.Eventuallyf(t, func() bool {
req := httptest.NewRequest(http.MethodGet, "/", nil).WithContext(ctx)
rec := httptest.NewRecorder()
r.ServeHTTP(rec, req)

got := codersdk.WorkspaceAgentListContainersResponse{}
err := json.NewDecoder(rec.Body).Decode(&got)
require.NoError(t, err)

return len(got.Devcontainers) >= 1
}, testutil.WaitShort, testutil.IntervalFast, "dev containers never found")

// Then: We expect the mock infra to not fail.
})
})
}
43 changes: 26 additions & 17 deletionscli/agent.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,23 +40,24 @@ import (

func (r *RootCmd) workspaceAgent() *serpent.Command {
var (
auth string
logDir string
scriptDataDir string
pprofAddress string
noReap bool
sshMaxTimeout time.Duration
tailnetListenPort int64
prometheusAddress string
debugAddress string
slogHumanPath string
slogJSONPath string
slogStackdriverPath string
blockFileTransfer bool
agentHeaderCommand string
agentHeader []string
devcontainers bool
devcontainerProjectDiscovery bool
auth string
logDir string
scriptDataDir string
pprofAddress string
noReap bool
sshMaxTimeout time.Duration
tailnetListenPort int64
prometheusAddress string
debugAddress string
slogHumanPath string
slogJSONPath string
slogStackdriverPath string
blockFileTransfer bool
agentHeaderCommand string
agentHeader []string
devcontainers bool
devcontainerProjectDiscovery bool
devcontainerDiscoveryAutostart bool
)
cmd := &serpent.Command{
Use: "agent",
Expand DownExpand Up@@ -366,6 +367,7 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
DevcontainerAPIOptions: []agentcontainers.Option{
agentcontainers.WithSubAgentURL(r.agentURL.String()),
agentcontainers.WithProjectDiscovery(devcontainerProjectDiscovery),
agentcontainers.WithDiscoveryAutostart(devcontainerDiscoveryAutostart),
},
})

Expand DownExpand Up@@ -519,6 +521,13 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
Description: "Allow the agent to search the filesystem for devcontainer projects.",
Value: serpent.BoolOf(&devcontainerProjectDiscovery),
},
{
Flag: "devcontainers-discovery-autostart-enable",
Default: "false",
Env: "CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE",
Description: "Allow the agent to autostart devcontainer projects it discovers based on their configuration.",
Value: serpent.BoolOf(&devcontainerDiscoveryAutostart),
},
}

return cmd
Expand Down
4 changes: 4 additions & 0 deletionscli/testdata/coder_agent_--help.golden
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,6 +33,10 @@ OPTIONS:
--debug-address string, $CODER_AGENT_DEBUG_ADDRESS (default: 127.0.0.1:2113)
The bind address to serve a debug HTTP server.

--devcontainers-discovery-autostart-enable bool, $CODER_AGENT_DEVCONTAINERS_DISCOVERY_AUTOSTART_ENABLE (default: false)
Allow the agent to autostart devcontainer projects it discovers based
on their configuration.

--devcontainers-enable bool, $CODER_AGENT_DEVCONTAINERS_ENABLE (default: true)
Allow the agent to automatically detect running devcontainers.

Expand Down
8 changes: 8 additions & 0 deletionscoderd/dynamicparameters/error.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,14 @@ func tagValidationError(diags hcl.Diagnostics) *DiagnosticError {
}
}

func presetValidationError(diags hcl.Diagnostics) *DiagnosticError {
return &DiagnosticError{
Message: "Unable to validate presets",
Diagnostics: diags,
KeyedDiagnostics: make(map[string]hcl.Diagnostics),
}
}

type DiagnosticError struct {
// Message is the human-readable message that will be returned to the user.
Message string
Expand Down
28 changes: 28 additions & 0 deletionscoderd/dynamicparameters/presets.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
package dynamicparameters

import (
"github.com/hashicorp/hcl/v2"

"github.com/coder/preview"
)

// CheckPresets extracts the preset related diagnostics from a template version preset
func CheckPresets(output *preview.Output, diags hcl.Diagnostics) *DiagnosticError {
de := presetValidationError(diags)
if output == nil {
return de
}

presets := output.Presets
for _, preset := range presets {
if hcl.Diagnostics(preset.Diagnostics).HasErrors() {
de.Extend(preset.Name, hcl.Diagnostics(preset.Diagnostics))
}
}

if de.HasError() {
return de
}

return nil
}
4 changes: 4 additions & 0 deletionscoderd/dynamicparameters/tags.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,10 @@ import (

func CheckTags(output *preview.Output, diags hcl.Diagnostics) *DiagnosticError {
de := tagValidationError(diags)
if output == nil {
return de
}

failedTags := output.WorkspaceTags.UnusableTags()
if len(failedTags) == 0 && !de.HasError() {
return nil // No errors, all is good!
Expand Down
8 changes: 8 additions & 0 deletionscoderd/templateversions.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1822,6 +1822,14 @@ func (api *API) dynamicTemplateVersionTags(ctx context.Context, rw http.Response
return nil, false
}

// Fails early if presets are invalid to prevent downstream workspace creation errors
presetErr := dynamicparameters.CheckPresets(output, nil)
if presetErr != nil {
code, resp := presetErr.Response()
httpapi.Write(ctx, rw, code, resp)
return nil, false
}

return output.WorkspaceTags.Tags(), true
}

Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp