mirror of
https://github.com/hanzoai/pack.git
synced 2026-09-30 23:43:13 +00:00
* fix: respect cache backend type for registry cache import/export * docs: update local development build instructions - Update local image building to use the provided project task. - Document the workflow for building with a local registry. - Add examples for configuring buildctl with caching and debugging flags. Generated-by: aiautocommit * refactor(buildkit): clean up code comments and formatting - Remove redundant comments and improve internal documentation. - Fix minor formatting inconsistencies in code blocks and comment descriptions. Generated-by: aiautocommit * feat: add ParseBool utility to handle common boolean string variants Generated-by: aiautocommit * feat: integrate local registry and buildkit configuration - Add buildkitd configuration to enable HTTP/insecure access to the local registry. - Introduce a local registry service container on port 7890. - Update the buildkit setup to mount the new registry configuration. - Add tasks for building the frontend image and running project builds using the local registry and buildctl. Generated-by: aiautocommit * docs: update CLAUDE.md with architecture and style guidance Generated-by: aiautocommit * feat: add support for multiple cache-from and cache-to build flags - Allow users to configure external cache sources and destinations via the `build` subcommand. - Update cache parsing logic to support multiple entries matching the Docker buildx CLI format. - Remove hardcoded default cache type to provide better control over BuildKit cache configurations. Generated-by: aiautocommit * test: add integration tests for cache-import parsing Generated-by: aiautocommit * refactor(buildkit): extract cache entry parsing logic - Centralize cache configuration logic by moving loop-based parsing into a reusable `cacheEntriesFromFlags` helper. - Improve code maintainability and readability by reducing duplication in `BuildWithBuildkitClient`. - Add comprehensive unit tests for cache entry processing, including edge cases for flag parsing and empty inputs. Generated-by: aiautocommit * fix(test): remove unused buildkit cache flags from integration tests * Remove unused flag variables that were meant for remote BuildKit caching. * Ensure integration tests avoid remote cache (e.g., type=gha) to prevent exceeding GitHub Actions cache limits and excessive eviction. Generated-by: aiautocommit * test(buildkit): consolidate cache import tests - Move TestParseCacheImports from its own file to frontend_test.go to consolidate related buildkit frontend tests. Generated-by: aiautocommit * style: fix indentation in build test helper Generated-by: aiautocommit * docs: document support for BuildKit cache backends Generated-by: aiautocommit * docs(developing-locally): add information on Docker, BuildKit, and caching - Add missing setup prerequisites. - Include debugging and configuration guidance for BuildKit/Docker. - Clarify cache export and import implementation expectations in Railpack. Generated-by: aiautocommit * docs: clarify cache flag parsing and pnpm version logic Generated-by: aiautocommit --------- Co-authored-by: Matt Van Horn <[email protected]> Co-authored-by: Michael Bianco <[email protected]> Co-authored-by: Hanzo Dev <[email protected]>
196 lines
4.8 KiB
Go
196 lines
4.8 KiB
Go
package buildkit
|
|
|
|
import (
|
|
"maps"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/moby/buildkit/client"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGetImageName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
appDir string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "lowercase directory name",
|
|
appDir: "/path/to/myapp",
|
|
expected: "myapp",
|
|
},
|
|
{
|
|
name: "uppercase directory name is lowercased",
|
|
appDir: "/path/to/SteelMC",
|
|
expected: "steelmc",
|
|
},
|
|
{
|
|
name: "mixed case directory name is lowercased",
|
|
appDir: "/path/to/MyApp",
|
|
expected: "myapp",
|
|
},
|
|
{
|
|
name: "directory name with hyphens",
|
|
appDir: "/path/to/my-app",
|
|
expected: "my-app",
|
|
},
|
|
{
|
|
name: "empty path returns fallback",
|
|
appDir: "",
|
|
expected: "railpack-app",
|
|
},
|
|
{
|
|
name: "path ending with separator",
|
|
appDir: "/path/to/myapp" + string(filepath.Separator),
|
|
expected: "railpack-app",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := getImageName(tt.appDir)
|
|
if got != tt.expected {
|
|
t.Errorf("getImageName(%q) = %q, want %q", tt.appDir, got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractCacheType(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expectedType string
|
|
expectedAttrs map[string]string
|
|
}{
|
|
{
|
|
name: "registry cache type is extracted",
|
|
input: "type=registry,ref=localhost:5555/cache",
|
|
expectedType: "registry",
|
|
expectedAttrs: map[string]string{
|
|
"ref": "localhost:5555/cache",
|
|
},
|
|
},
|
|
{
|
|
name: "mode max kept in attrs",
|
|
input: "type=registry,ref=host.docker.internal:7890/node-bun:cache,mode=max",
|
|
expectedType: "registry",
|
|
expectedAttrs: map[string]string{
|
|
"ref": "host.docker.internal:7890/node-bun:cache",
|
|
"mode": "max",
|
|
},
|
|
},
|
|
{
|
|
name: "gha shape",
|
|
input: "type=gha,scope=my-cache",
|
|
expectedType: "gha",
|
|
expectedAttrs: map[string]string{
|
|
"scope": "my-cache",
|
|
},
|
|
},
|
|
{
|
|
name: "type only",
|
|
input: "type=registry",
|
|
expectedType: "registry",
|
|
expectedAttrs: map[string]string{},
|
|
},
|
|
{
|
|
name: "spaces around keys and values",
|
|
input: " type = registry , ref = myapp:cache ",
|
|
expectedType: "registry",
|
|
expectedAttrs: map[string]string{
|
|
"ref": "myapp:cache",
|
|
},
|
|
},
|
|
{
|
|
name: "missing type is not defaulted",
|
|
input: "scope=my-cache,mode=max",
|
|
expectedType: "",
|
|
expectedAttrs: map[string]string{
|
|
"scope": "my-cache",
|
|
"mode": "max",
|
|
},
|
|
},
|
|
{
|
|
name: "empty attrs",
|
|
input: "",
|
|
expectedType: "",
|
|
expectedAttrs: map[string]string{},
|
|
},
|
|
{
|
|
name: "skips segments without equals",
|
|
input: "type=registry,notavalue,ref=x",
|
|
expectedType: "registry",
|
|
expectedAttrs: map[string]string{
|
|
"ref": "x",
|
|
},
|
|
},
|
|
{
|
|
name: "value may contain equals",
|
|
input: "type=registry,ref=image:tag=latest",
|
|
expectedType: "registry",
|
|
expectedAttrs: map[string]string{
|
|
"ref": "image:tag=latest",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotType, gotAttrs := extractCacheType(parseKeyValue(tt.input))
|
|
if gotType != tt.expectedType {
|
|
t.Errorf("extractCacheType(%q) type = %q, want %q", tt.input, gotType, tt.expectedType)
|
|
}
|
|
if !maps.Equal(gotAttrs, tt.expectedAttrs) {
|
|
t.Errorf("extractCacheType(%q) attrs = %v, want %v", tt.input, gotAttrs, tt.expectedAttrs)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCacheEntriesFromFlags(t *testing.T) {
|
|
t.Run("nil slice", func(t *testing.T) {
|
|
require.Nil(t, cacheEntriesFromFlags(nil))
|
|
})
|
|
|
|
t.Run("empty slice", func(t *testing.T) {
|
|
require.Nil(t, cacheEntriesFromFlags([]string{}))
|
|
})
|
|
|
|
t.Run("skips empty strings", func(t *testing.T) {
|
|
got := cacheEntriesFromFlags([]string{"", "type=registry,ref=x", ""})
|
|
require.Equal(t, []client.CacheOptionsEntry{
|
|
{Type: "registry", Attrs: map[string]string{"ref": "x"}},
|
|
}, got)
|
|
})
|
|
|
|
t.Run("multiple registry entries", func(t *testing.T) {
|
|
got := cacheEntriesFromFlags([]string{
|
|
"type=registry,ref=myapp:cache-main",
|
|
"type=registry,ref=myapp:cache-branch",
|
|
})
|
|
require.Equal(t, []client.CacheOptionsEntry{
|
|
{Type: "registry", Attrs: map[string]string{"ref": "myapp:cache-main"}},
|
|
{Type: "registry", Attrs: map[string]string{"ref": "myapp:cache-branch"}},
|
|
}, got)
|
|
})
|
|
|
|
t.Run("mixed registry and gha with mode", func(t *testing.T) {
|
|
got := cacheEntriesFromFlags([]string{
|
|
"type=registry,ref=host.docker.internal:7890/node-bun:cache,mode=max",
|
|
"type=gha,scope=ci",
|
|
})
|
|
require.Equal(t, []client.CacheOptionsEntry{
|
|
{
|
|
Type: "registry",
|
|
Attrs: map[string]string{
|
|
"ref": "host.docker.internal:7890/node-bun:cache",
|
|
"mode": "max",
|
|
},
|
|
},
|
|
{Type: "gha", Attrs: map[string]string{"scope": "ci"}},
|
|
}, got)
|
|
})
|
|
}
|