Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 11 additions & 4 deletions .dagger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,27 @@ func (m *ContainerUse) Release(ctx context.Context,
// GitHub org name for package publishing, set only if testing release process on a personal fork
//+default="dagger"
githubOrgName string,
// Chocolatey API key for Windows package publishing
//+optional
chocolateyApiKey *dagger.Secret,
) (string, error) {
// Create custom container with nix package for nix-hash binary
customContainer := dag.Container().
From("ghcr.io/goreleaser/goreleaser:latest").
WithExec([]string{"apk", "add", "nix"})

// Use custom container with Goreleaser
return dag.Goreleaser(m.Source, dagger.GoreleaserOpts{
gr := dag.Goreleaser(m.Source, dagger.GoreleaserOpts{
Container: customContainer,
}).
WithSecretVariable("GITHUB_TOKEN", githubToken).
WithEnvVariable("GH_ORG_NAME", githubOrgName).
Release().
Run(ctx)
WithEnvVariable("GH_ORG_NAME", githubOrgName)

if chocolateyApiKey != nil {
gr = gr.WithSecretVariable("CHOCOLATEY_API_KEY", chocolateyApiKey)
}

return gr.Release().Run(ctx)
}

// Test runs the test suite
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
with:
version: "latest"
verb: call
args: release --version "${GITHUB_REF#refs/tags/}" --github-token env:RELEASE_GITHUB_TOKEN --github-org-name=${{ github.repository_owner }}
args: release --version "${GITHUB_REF#refs/tags/}" --github-token env:RELEASE_GITHUB_TOKEN --github-org-name=${{ github.repository_owner }} --chocolatey-api-key env:CHOCOLATEY_API_KEY
env:
RELEASE_GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
52 changes: 52 additions & 0 deletions .github/workflows/test-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Test Windows

on:
push:
branches: ['**']
workflow_dispatch:

jobs:
test-windows:
name: Test Windows
runs-on: windows-latest
env:
_EXPERIMENTAL_DAGGER_RUNNER_HOST: ${{ secrets._EXPERIMENTAL_DAGGER_RUNNER_HOST }}
DAGGER_CLOUD_TOKEN: ${{ secrets.DAGGER_CLOUD_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Configure Git
run: |
git config --global user.email "test@example.com"
git config --global user.name "Test User"

- name: Install Dagger
shell: pwsh
run: |
choco install dagger -y
echo "$Env:ChocolateyInstall\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append

- name: Verify Dagger installation
shell: pwsh
run: dagger version

- name: Download dependencies
run: go mod download

- name: Run tests
run: go test -v -race ./...

- name: Build
run: go build -v -o container-use.exe ./cmd/container-use

- name: Smoke test
run: |
.\container-use.exe version
.\container-use.exe --help
.\container-use.exe completion powershell
34 changes: 34 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ archives:
ids:
- container-use
name_template: "{{ .ProjectName }}_{{ .Tag }}_{{ .Os }}_{{ .Arch }}"
format_overrides:
- goos: windows
formats: [zip]
files:
- README.md
- LICENSE
Expand Down Expand Up @@ -131,6 +134,37 @@ nix:
--fish <($out/bin/cu completion fish) \
--zsh <($out/bin/cu completion zsh)

# chocolateys:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not working?

# - name: container-use
# ids:
# - container-use-archive
# owners: Dagger
# title: Container Use
# authors: Dagger Team
# project_url: https://github.com/dagger/container-use
# url_template: "https://github.com/dagger/container-use/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
# icon_url: https://raw.githubusercontent.com/dagger/container-use/main/docs/images/dagger-icon.png
# copyright: 2025 Dagger, Inc.
# license_url: https://github.com/dagger/container-use/blob/main/LICENSE
# require_license_acceptance: false
# project_source_url: https://github.com/dagger/container-use
# docs_url: https://container-use.com/
# bug_tracker_url: https://github.com/dagger/container-use/issues
# tags: "container docker mcp agent development cli devtools"
# summary: Containerized environments for coding agents
# description: |
# Container Use provides isolated, containerized environments for AI coding agents using Docker and Git.

# Features:
# - Isolated environments for AI agents to work safely
# - Git-based version control for all changes
# - Docker containers for consistent development environments
# - Model Context Protocol (MCP) integration
# - Support for multiple popular AI coding assistants
# release_notes: "https://github.com/dagger/container-use/releases/tag/{{ .Tag }}"
# api_key: "{{ .Env.CHOCOLATEY_API_KEY }}"
# skip_publish: auto

checksum:
name_template: "checksums.txt"

Expand Down
9 changes: 7 additions & 2 deletions cmd/container-use/main_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"sync"
"testing"

Expand All @@ -20,15 +21,19 @@ var (
func getContainerUseBinary(t *testing.T) string {
binaryPathOnce.Do(func() {
t.Log("Building fresh container-use binary...")
cmd := exec.Command("go", "build", "-o", "container-use", ".")
binaryName := "container-use"
if runtime.GOOS == "windows" {
binaryName = "container-use.exe"
}
Comment on lines +24 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit, but kinda a big one: use build directives instead of conditional logic -- maybe fix in a follow-up?

cmd := exec.Command("go", "build", "-o", binaryName, ".")
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
t.Fatalf("Failed to build container-use binary: %v", err)
}

abs, err := filepath.Abs("container-use")
abs, err := filepath.Abs(binaryName)
if err != nil {
t.Fatalf("Failed to get absolute path: %v", err)
}
Expand Down
60 changes: 60 additions & 0 deletions cmd/container-use/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main_test

import (
"log/slog"
"os"
"path/filepath"
"runtime"
"testing"
)

func TestMain(m *testing.M) {
Copy link
Contributor

@cwlbraa cwlbraa Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the pr description explained why all this faff was necessary on windows, but do we really need to fuck with it on unixes too?

(implicitly, couldn't this be done with build directives?)

// Create a short root; on Windows prefer C:\Temp
root := shortRoot("cu-stdio")
cache := filepath.Join(root, "cache")
tmp := filepath.Join(root, "tmp")
app := filepath.Join(root, "appdata")
lapp := filepath.Join(root, "localappdata")
_ = os.MkdirAll(cache, 0o755)
_ = os.MkdirAll(tmp, 0o755)
_ = os.MkdirAll(app, 0o755)
_ = os.MkdirAll(lapp, 0o755)

// Shared app/data home for all child servers
_ = os.Setenv("XDG_CACHE_HOME", cache)
if runtime.GOOS == "windows" {
_ = os.Setenv("TEMP", tmp)
_ = os.Setenv("TMP", tmp)
_ = os.Setenv("APPDATA", app)
_ = os.Setenv("LOCALAPPDATA", lapp)
} else {
_ = os.Setenv("TMPDIR", tmp)
}

// Make Git allow long paths without touching system/global config
gitcfg := filepath.Join(root, "gitconfig")
_ = os.WriteFile(gitcfg, []byte("[core]\nlongpaths = true\n"), 0o644)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL, how long are these paths that they have a special flag? lmao

_ = os.Setenv("GIT_CONFIG_GLOBAL", gitcfg)

if os.Getenv("TEST_VERBOSE") != "" {
slog.Info("stdio test cache configured",
"XDG_CACHE_HOME", cache,
"TEMP/TMP/TMPDIR", tmp,
"APPDATA", app)
}

code := m.Run()
_ = os.RemoveAll(root)
os.Exit(code)
}

func shortRoot(prefix string) string {
if runtime.GOOS != "windows" {
dir, _ := os.MkdirTemp("", prefix+"-")
return dir
}
base := `C:\Temp`
_ = os.MkdirAll(base, 0o755)
dir, _ := os.MkdirTemp(base, prefix+"-")
return dir
}
Loading