feat(build): ENV-first Deno + discovery metadata (os/arch/github ref) + Xcode Cloud
- env.go (new): DENO_ENABLE and DENO_BUILD environment variables activate Deno builds even when repo only has package.json or bare frontend/ dir - wails.go + node.go + apple.go + release.yml + xcode_cloud.go: honor the ENV flags across builder + workflow + Xcode Cloud script generation - discovery.go: record host os/arch + GitHub ref metadata (ref, branch, tag, is_tag, sha, short_sha, repo, owner) - api/provider.go: /discover exposes the new metadata - Regression coverage across discovery/builders/apple/workflow/xcode_cloud/api Verified: go test ./... passes Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
cbdb8028dc
commit
293dfd6e66
16 changed files with 377 additions and 8 deletions
|
|
@ -175,6 +175,8 @@ func TestBuildCmd_RunReleaseWorkflow_Good(t *testing.T) {
|
|||
assert.Contains(t, content, "libwebkit2gtk-4.1-dev")
|
||||
assert.Contains(t, content, "Install MkDocs")
|
||||
assert.Contains(t, content, "Setup Deno")
|
||||
assert.Contains(t, content, "env.DENO_ENABLE == 'true'")
|
||||
assert.Contains(t, content, "inputs.deno-build != ''")
|
||||
assert.Contains(t, content, "build-cache:")
|
||||
assert.Contains(t, content, "Restore build cache")
|
||||
assert.Contains(t, content, "actions/cache@v4")
|
||||
|
|
@ -236,6 +238,8 @@ func TestBuildCmd_RunReleaseWorkflow_Good(t *testing.T) {
|
|||
assert.Contains(t, content, "Install Linux Wails dependencies")
|
||||
assert.Contains(t, content, "Install MkDocs")
|
||||
assert.Contains(t, content, "Setup Deno")
|
||||
assert.Contains(t, content, "env.DENO_ENABLE == 'true'")
|
||||
assert.Contains(t, content, "inputs.deno-build != ''")
|
||||
assert.Contains(t, content, "build-cache:")
|
||||
assert.Contains(t, content, "Restore build cache")
|
||||
assert.Contains(t, content, "--sign=false")
|
||||
|
|
|
|||
|
|
@ -332,6 +332,8 @@ func (p *BuildProvider) discoverProject(c *gin.Context) {
|
|||
|
||||
c.JSON(http.StatusOK, api.OK(map[string]any{
|
||||
"types": typeStrings,
|
||||
"os": discovery.OS,
|
||||
"arch": discovery.Arch,
|
||||
"primary": primary,
|
||||
"primary_stack": discovery.PrimaryStack,
|
||||
"suggested_stack": discovery.SuggestedStack,
|
||||
|
|
@ -339,6 +341,14 @@ func (p *BuildProvider) discoverProject(c *gin.Context) {
|
|||
"has_frontend": discovery.HasFrontend,
|
||||
"has_subtree_npm": discovery.HasSubtreeNpm,
|
||||
"linux_packages": discovery.LinuxPackages,
|
||||
"ref": discovery.Ref,
|
||||
"branch": discovery.Branch,
|
||||
"tag": discovery.Tag,
|
||||
"is_tag": discovery.IsTag,
|
||||
"sha": discovery.SHA,
|
||||
"short_sha": discovery.ShortSHA,
|
||||
"repo": discovery.Repo,
|
||||
"owner": discovery.Owner,
|
||||
"build_options": options.String(),
|
||||
"options": map[string]any{
|
||||
"obfuscate": options.Obfuscate,
|
||||
|
|
|
|||
|
|
@ -944,6 +944,9 @@ func TestProvider_GenerateReleaseWorkflow_EmptyBody_Good(t *testing.T) {
|
|||
|
||||
func TestProvider_DiscoverProject_Good(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
t.Setenv("GITHUB_SHA", "0123456789abcdef")
|
||||
t.Setenv("GITHUB_REF", "refs/heads/main")
|
||||
t.Setenv("GITHUB_REPOSITORY", "dappcore/core")
|
||||
|
||||
projectDir := t.TempDir()
|
||||
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "go.mod"), []byte("module example"), 0o644))
|
||||
|
|
@ -975,12 +978,21 @@ build:
|
|||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
body := recorder.Body.String()
|
||||
assert.Contains(t, body, `"types":["wails","go","node"]`)
|
||||
assert.Contains(t, body, `"os":"`)
|
||||
assert.Contains(t, body, `"arch":"`)
|
||||
assert.Contains(t, body, `"primary":"wails"`)
|
||||
assert.Contains(t, body, `"primary_stack":"wails"`)
|
||||
assert.Contains(t, body, `"suggested_stack":"wails2"`)
|
||||
assert.Contains(t, body, `"has_frontend":true`)
|
||||
assert.Contains(t, body, `"has_subtree_npm":false`)
|
||||
assert.Contains(t, body, `"linux_packages":`)
|
||||
assert.Contains(t, body, `"ref":"refs/heads/main"`)
|
||||
assert.Contains(t, body, `"branch":"main"`)
|
||||
assert.Contains(t, body, `"is_tag":false`)
|
||||
assert.Contains(t, body, `"sha":"0123456789abcdef"`)
|
||||
assert.Contains(t, body, `"short_sha":"0123456"`)
|
||||
assert.Contains(t, body, `"repo":"dappcore/core"`)
|
||||
assert.Contains(t, body, `"owner":"dappcore"`)
|
||||
assert.Contains(t, body, `"build_options":"`)
|
||||
assert.Contains(t, body, `"-obfuscated`)
|
||||
assert.Contains(t, body, `"options":{"ldflags":["-s","-w"],"nsis":true,"obfuscate":true`)
|
||||
|
|
|
|||
|
|
@ -658,10 +658,17 @@ func prepareWailsFrontend(ctx context.Context, cfg WailsBuildConfig) error {
|
|||
func resolveWailsFrontendBuild(cfg WailsBuildConfig) (string, string, []string, error) {
|
||||
frontendDir := resolveFrontendDir(io.Local, cfg.ProjectDir)
|
||||
if frontendDir == "" {
|
||||
return "", "", nil, nil
|
||||
if DenoRequested(cfg.DenoBuild) {
|
||||
frontendDir = cfg.ProjectDir
|
||||
if io.Local.IsDir(ax.Join(cfg.ProjectDir, "frontend")) {
|
||||
frontendDir = ax.Join(cfg.ProjectDir, "frontend")
|
||||
}
|
||||
} else {
|
||||
return "", "", nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
if hasDenoConfig(io.Local, frontendDir) {
|
||||
if hasDenoConfig(io.Local, frontendDir) || DenoRequested(cfg.DenoBuild) {
|
||||
command, args, err := resolveDenoBuildCommand(cfg)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
|
|
@ -686,7 +693,18 @@ func resolveFrontendDir(filesystem io.Medium, projectDir string) string {
|
|||
return projectDir
|
||||
}
|
||||
|
||||
return resolveSubtreeFrontendDir(filesystem, projectDir)
|
||||
if nested := resolveSubtreeFrontendDir(filesystem, projectDir); nested != "" {
|
||||
return nested
|
||||
}
|
||||
|
||||
if DenoRequested("") {
|
||||
if filesystem.IsDir(frontendDir) {
|
||||
return frontendDir
|
||||
}
|
||||
return projectDir
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func hasDenoConfig(filesystem io.Medium, dir string) bool {
|
||||
|
|
|
|||
|
|
@ -354,6 +354,64 @@ func TestApple_BuildWailsApp_PreBuildsFrontendAndForcesCGO_Good(t *testing.T) {
|
|||
assert.Equal(t, "wails3", calls[1].command)
|
||||
}
|
||||
|
||||
func TestApple_BuildWailsApp_UsesDenoWhenEnabledWithoutManifest_Good(t *testing.T) {
|
||||
projectDir := t.TempDir()
|
||||
bundlePath := ax.Join(projectDir, "build", "bin", "Core.app")
|
||||
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "package.json"), []byte(`{}`), 0o644))
|
||||
t.Setenv("DENO_ENABLE", "true")
|
||||
|
||||
oldResolve := appleResolveCommand
|
||||
oldCombined := appleCombinedOutput
|
||||
t.Cleanup(func() {
|
||||
appleResolveCommand = oldResolve
|
||||
appleCombinedOutput = oldCombined
|
||||
})
|
||||
|
||||
var calls []struct {
|
||||
dir string
|
||||
command string
|
||||
args []string
|
||||
}
|
||||
|
||||
appleResolveCommand = func(name string, fallbackPaths ...string) (string, error) {
|
||||
return name, nil
|
||||
}
|
||||
appleCombinedOutput = func(ctx context.Context, dir string, env []string, command string, args ...string) (string, error) {
|
||||
calls = append(calls, struct {
|
||||
dir string
|
||||
command string
|
||||
args []string
|
||||
}{
|
||||
dir: dir,
|
||||
command: command,
|
||||
args: append([]string{}, args...),
|
||||
})
|
||||
|
||||
switch command {
|
||||
case "deno":
|
||||
assert.Equal(t, projectDir, dir)
|
||||
assert.Equal(t, []string{"task", "build"}, args)
|
||||
case "wails3":
|
||||
writeDummyAppBundle(t, bundlePath, "Core", "built")
|
||||
default:
|
||||
t.Fatalf("unexpected command: %s", command)
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
result, err := BuildWailsApp(context.Background(), WailsBuildConfig{
|
||||
ProjectDir: projectDir,
|
||||
Name: "Core",
|
||||
Arch: "arm64",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, bundlePath, result)
|
||||
require.Len(t, calls, 2)
|
||||
assert.Equal(t, "deno", calls[0].command)
|
||||
assert.Equal(t, "wails3", calls[1].command)
|
||||
}
|
||||
|
||||
func TestApple_BuildApple_Good(t *testing.T) {
|
||||
projectDir := t.TempDir()
|
||||
outputDir := ax.Join(projectDir, "dist", "apple")
|
||||
|
|
|
|||
|
|
@ -182,7 +182,12 @@ func (b *NodeBuilder) resolvePackageManager(fs io.Medium, projectDir string) (st
|
|||
//
|
||||
// command, args, err := b.resolveBuildCommand("npm")
|
||||
func (b *NodeBuilder) resolveBuildCommand(cfg *build.Config, fs io.Medium, projectDir string) (string, []string, error) {
|
||||
if b.hasDenoConfig(fs, projectDir) {
|
||||
configuredDenoBuild := ""
|
||||
if cfg != nil {
|
||||
configuredDenoBuild = cfg.DenoBuild
|
||||
}
|
||||
|
||||
if b.hasDenoConfig(fs, projectDir) || build.DenoRequested(configuredDenoBuild) {
|
||||
return resolveDenoBuildCommand(cfg, b.resolveDenoCli)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -300,6 +300,85 @@ func TestNode_NodeBuilderBuild_Good_DenoOverrideFromEnvWins(t *testing.T) {
|
|||
assert.Equal(t, "--env", lines[1])
|
||||
}
|
||||
|
||||
func TestNode_NodeBuilderBuild_Good_DenoEnableWithoutManifest(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test in short mode")
|
||||
}
|
||||
|
||||
binDir := t.TempDir()
|
||||
setupFakeNodeToolchain(t, binDir)
|
||||
t.Setenv("PATH", binDir+string(os.PathListSeparator)+os.Getenv("PATH"))
|
||||
t.Setenv("DENO_ENABLE", "true")
|
||||
|
||||
projectDir := t.TempDir()
|
||||
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "package.json"), []byte(`{}`), 0o644))
|
||||
|
||||
outputDir := t.TempDir()
|
||||
logPath := ax.Join(t.TempDir(), "deno-enable.log")
|
||||
t.Setenv("NODE_BUILD_LOG_FILE", logPath)
|
||||
|
||||
builder := NewNodeBuilder()
|
||||
cfg := &build.Config{
|
||||
FS: io.Local,
|
||||
ProjectDir: projectDir,
|
||||
OutputDir: outputDir,
|
||||
Name: "denoapp",
|
||||
}
|
||||
|
||||
artifacts, err := builder.Build(context.Background(), cfg, []build.Target{{OS: "linux", Arch: "amd64"}})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, artifacts, 1)
|
||||
|
||||
content, err := ax.ReadFile(logPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(content)), "\n")
|
||||
require.GreaterOrEqual(t, len(lines), 3)
|
||||
assert.Equal(t, "deno", lines[0])
|
||||
assert.Equal(t, "task", lines[1])
|
||||
assert.Equal(t, "build", lines[2])
|
||||
}
|
||||
|
||||
func TestNode_NodeBuilderBuild_Good_DenoOverrideWithoutManifest(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test in short mode")
|
||||
}
|
||||
|
||||
binDir := t.TempDir()
|
||||
setupFakeNodeToolchain(t, binDir)
|
||||
setupFakeNodeCommand(t, binDir, "deno-build")
|
||||
t.Setenv("PATH", binDir+string(os.PathListSeparator)+os.Getenv("PATH"))
|
||||
|
||||
projectDir := t.TempDir()
|
||||
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "package.json"), []byte(`{}`), 0o644))
|
||||
|
||||
outputDir := t.TempDir()
|
||||
logPath := ax.Join(t.TempDir(), "deno-config.log")
|
||||
t.Setenv("NODE_BUILD_LOG_FILE", logPath)
|
||||
|
||||
builder := NewNodeBuilder()
|
||||
cfg := &build.Config{
|
||||
FS: io.Local,
|
||||
ProjectDir: projectDir,
|
||||
OutputDir: outputDir,
|
||||
Name: "denoapp",
|
||||
DenoBuild: "deno-build --target release",
|
||||
}
|
||||
|
||||
artifacts, err := builder.Build(context.Background(), cfg, []build.Target{{OS: "linux", Arch: "amd64"}})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, artifacts, 1)
|
||||
|
||||
content, err := ax.ReadFile(logPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(content)), "\n")
|
||||
require.GreaterOrEqual(t, len(lines), 3)
|
||||
assert.Equal(t, "deno-build", lines[0])
|
||||
assert.Equal(t, "--target", lines[1])
|
||||
assert.Equal(t, "release", lines[2])
|
||||
}
|
||||
|
||||
func TestNode_ResolvePackageManager_Good(t *testing.T) {
|
||||
fs := io.Local
|
||||
builder := NewNodeBuilder()
|
||||
|
|
|
|||
|
|
@ -248,10 +248,18 @@ func (b *WailsBuilder) resolveFrontendBuild(cfg *build.Config) (string, string,
|
|||
projectDir := cfg.ProjectDir
|
||||
frontendDir := b.resolveFrontendDir(fs, projectDir)
|
||||
if frontendDir == "" {
|
||||
return "", "", nil, nil
|
||||
if build.DenoRequested(cfg.DenoBuild) {
|
||||
if fs.IsDir(ax.Join(projectDir, "frontend")) {
|
||||
frontendDir = ax.Join(projectDir, "frontend")
|
||||
} else {
|
||||
frontendDir = projectDir
|
||||
}
|
||||
} else {
|
||||
return "", "", nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
if b.hasDenoConfig(fs, frontendDir) {
|
||||
if b.hasDenoConfig(fs, frontendDir) || build.DenoRequested(cfg.DenoBuild) {
|
||||
command, args, err := resolveDenoBuildCommand(cfg, b.resolveDenoCli)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
|
|
@ -312,6 +320,13 @@ func (b *WailsBuilder) resolveFrontendDir(fs io.Medium, projectDir string) strin
|
|||
return nestedFrontendDir
|
||||
}
|
||||
|
||||
if build.DenoRequested("") {
|
||||
if fs.IsDir(frontendDir) {
|
||||
return frontendDir
|
||||
}
|
||||
return projectDir
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -471,6 +471,17 @@ func TestWails_WailsBuilderResolveFrontendDir_Good(t *testing.T) {
|
|||
got := builder.resolveFrontendDir(fs, projectDir)
|
||||
assert.Empty(t, got)
|
||||
})
|
||||
|
||||
t.Run("falls back to frontend directory when DENO_ENABLE is set", func(t *testing.T) {
|
||||
t.Setenv("DENO_ENABLE", "true")
|
||||
|
||||
projectDir := t.TempDir()
|
||||
frontendDir := ax.Join(projectDir, "frontend")
|
||||
require.NoError(t, ax.MkdirAll(frontendDir, 0o755))
|
||||
|
||||
got := builder.resolveFrontendDir(fs, projectDir)
|
||||
assert.Equal(t, frontendDir, got)
|
||||
})
|
||||
}
|
||||
|
||||
func TestWails_WailsBuilderBuildV2_Good(t *testing.T) {
|
||||
|
|
@ -757,6 +768,68 @@ func TestWails_WailsBuilderPreBuild_Good(t *testing.T) {
|
|||
assert.Equal(t, "build", lines[2])
|
||||
})
|
||||
|
||||
t.Run("prefers deno when DENO_ENABLE is set without a deno manifest", func(t *testing.T) {
|
||||
binDir := t.TempDir()
|
||||
setupFakeFrontendCommand(t, binDir, "deno")
|
||||
setupFakeFrontendCommand(t, binDir, "npm")
|
||||
t.Setenv("PATH", binDir+string(os.PathListSeparator)+os.Getenv("PATH"))
|
||||
t.Setenv("DENO_ENABLE", "true")
|
||||
|
||||
projectDir := setupWailsTestProject(t)
|
||||
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "package.json"), []byte(`{}`), 0o644))
|
||||
|
||||
logPath := ax.Join(t.TempDir(), "frontend-deno-enable.log")
|
||||
t.Setenv("BUILD_SEQUENCE_FILE", logPath)
|
||||
|
||||
builder := NewWailsBuilder()
|
||||
cfg := &build.Config{
|
||||
FS: io.Local,
|
||||
ProjectDir: projectDir,
|
||||
}
|
||||
|
||||
require.NoError(t, builder.PreBuild(context.Background(), cfg))
|
||||
|
||||
content, err := ax.ReadFile(logPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(content)), "\n")
|
||||
require.Len(t, lines, 3)
|
||||
assert.Equal(t, "deno", lines[0])
|
||||
assert.Equal(t, "task", lines[1])
|
||||
assert.Equal(t, "build", lines[2])
|
||||
})
|
||||
|
||||
t.Run("uses configured deno build command without a deno manifest", func(t *testing.T) {
|
||||
binDir := t.TempDir()
|
||||
setupFakeFrontendCommand(t, binDir, "deno-build")
|
||||
setupFakeFrontendCommand(t, binDir, "npm")
|
||||
t.Setenv("PATH", binDir+string(os.PathListSeparator)+os.Getenv("PATH"))
|
||||
|
||||
projectDir := setupWailsTestProject(t)
|
||||
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "package.json"), []byte(`{}`), 0o644))
|
||||
|
||||
logPath := ax.Join(t.TempDir(), "frontend-config-deno.log")
|
||||
t.Setenv("BUILD_SEQUENCE_FILE", logPath)
|
||||
|
||||
builder := NewWailsBuilder()
|
||||
cfg := &build.Config{
|
||||
FS: io.Local,
|
||||
ProjectDir: projectDir,
|
||||
DenoBuild: "deno-build --target release",
|
||||
}
|
||||
|
||||
require.NoError(t, builder.PreBuild(context.Background(), cfg))
|
||||
|
||||
content, err := ax.ReadFile(logPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(content)), "\n")
|
||||
require.Len(t, lines, 3)
|
||||
assert.Equal(t, "deno-build", lines[0])
|
||||
assert.Equal(t, "--target", lines[1])
|
||||
assert.Equal(t, "release", lines[2])
|
||||
})
|
||||
|
||||
t.Run("discovers nested package.json in a monorepo", func(t *testing.T) {
|
||||
binDir := t.TempDir()
|
||||
setupFakeFrontendCommand(t, binDir, "npm")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package build
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"dappco.re/go/core"
|
||||
"dappco.re/go/core/build/internal/ax"
|
||||
"dappco.re/go/core/io"
|
||||
|
|
@ -274,6 +276,10 @@ func IsRustProject(fs io.Medium, dir string) bool {
|
|||
type DiscoveryResult struct {
|
||||
// Types lists all detected project types in priority order.
|
||||
Types []ProjectType
|
||||
// OS is the current host operating system for the discovery run.
|
||||
OS string
|
||||
// Arch is the current host architecture for the discovery run.
|
||||
Arch string
|
||||
// PrimaryStack is the best stack suggestion based on detected types.
|
||||
PrimaryStack string
|
||||
// SuggestedStack is the richer action-oriented stack hint derived from markers.
|
||||
|
|
@ -291,6 +297,22 @@ type DiscoveryResult struct {
|
|||
// Distro holds the detected Linux distribution version (e.g., "24.04").
|
||||
// Used by ComputeOptions to inject webkit2_41 tag on Ubuntu 24.04+.
|
||||
Distro string
|
||||
// Ref is the Git ref when discovery runs under GitHub metadata.
|
||||
Ref string
|
||||
// Branch is the branch name when available from GitHub metadata.
|
||||
Branch string
|
||||
// Tag is the tag name when available from GitHub metadata.
|
||||
Tag string
|
||||
// IsTag reports whether Ref points at a tag.
|
||||
IsTag bool
|
||||
// SHA is the current GitHub commit SHA when available.
|
||||
SHA string
|
||||
// ShortSHA is the short GitHub commit SHA when available.
|
||||
ShortSHA string
|
||||
// Repo is the GitHub owner/repo string when available.
|
||||
Repo string
|
||||
// Owner is the GitHub repository owner when available.
|
||||
Owner string
|
||||
}
|
||||
|
||||
// DiscoverFull returns a rich discovery result with all markers and metadata.
|
||||
|
|
@ -305,6 +327,8 @@ func DiscoverFull(fs io.Medium, dir string) (*DiscoveryResult, error) {
|
|||
|
||||
result := &DiscoveryResult{
|
||||
Types: types,
|
||||
OS: runtime.GOOS,
|
||||
Arch: runtime.GOARCH,
|
||||
Markers: make(map[string]bool),
|
||||
}
|
||||
|
||||
|
|
@ -342,6 +366,16 @@ func DiscoverFull(fs io.Medium, dir string) (*DiscoveryResult, error) {
|
|||
// Linux distro detection: used for distro-sensitive build flags.
|
||||
result.Distro = detectDistroVersion(fs)
|
||||
result.LinuxPackages = ResolveLinuxPackages(result.Types, result.Distro)
|
||||
if git := DetectGitHubMetadata(); git != nil {
|
||||
result.Ref = git.Ref
|
||||
result.Branch = git.Branch
|
||||
result.Tag = git.Tag
|
||||
result.IsTag = git.IsTag
|
||||
result.SHA = git.SHA
|
||||
result.ShortSHA = git.ShortSHA
|
||||
result.Repo = git.Repo
|
||||
result.Owner = git.Owner
|
||||
}
|
||||
|
||||
// Primary stack: first detected type as string, or empty
|
||||
if len(types) > 0 {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package build
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"dappco.re/go/core/build/internal/ax"
|
||||
|
|
@ -778,6 +779,8 @@ func TestDiscovery_DiscoverFull_Good(t *testing.T) {
|
|||
result, err := DiscoverFull(fs, dir)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []ProjectType{ProjectTypeGo}, result.Types)
|
||||
assert.Equal(t, runtime.GOOS, result.OS)
|
||||
assert.Equal(t, runtime.GOARCH, result.Arch)
|
||||
assert.Equal(t, "go", result.PrimaryStack)
|
||||
assert.Equal(t, "go", result.SuggestedStack)
|
||||
assert.False(t, result.HasFrontend)
|
||||
|
|
@ -786,6 +789,23 @@ func TestDiscovery_DiscoverFull_Good(t *testing.T) {
|
|||
assert.False(t, result.Markers["wails.json"])
|
||||
})
|
||||
|
||||
t.Run("captures GitHub metadata when available", func(t *testing.T) {
|
||||
t.Setenv("GITHUB_SHA", "0123456789abcdef")
|
||||
t.Setenv("GITHUB_REF", "refs/tags/v1.2.3")
|
||||
t.Setenv("GITHUB_REPOSITORY", "dappcore/core")
|
||||
|
||||
dir := setupTestDir(t, "go.mod")
|
||||
result, err := DiscoverFull(fs, dir)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "refs/tags/v1.2.3", result.Ref)
|
||||
assert.Equal(t, "v1.2.3", result.Tag)
|
||||
assert.True(t, result.IsTag)
|
||||
assert.Equal(t, "0123456789abcdef", result.SHA)
|
||||
assert.Equal(t, "0123456", result.ShortSHA)
|
||||
assert.Equal(t, "dappcore/core", result.Repo)
|
||||
assert.Equal(t, "dappcore", result.Owner)
|
||||
})
|
||||
|
||||
t.Run("returns complete result for Go workspace project", func(t *testing.T) {
|
||||
dir := setupTestDir(t, "go.work")
|
||||
result, err := DiscoverFull(fs, dir)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package build
|
||||
|
||||
import "dappco.re/go/core"
|
||||
|
||||
// BuildEnvironment returns a fresh environment slice that includes the
|
||||
// configured build environment, any derived cache variables, and optional
|
||||
// builder-specific values.
|
||||
|
|
@ -21,3 +23,27 @@ func BuildEnvironment(cfg *Config, extra ...string) []string {
|
|||
|
||||
return env
|
||||
}
|
||||
|
||||
// DenoRequested reports whether the current build should prefer a Deno-backed
|
||||
// frontend build. It honours the action-style environment overrides first and
|
||||
// then the persisted/configured command override.
|
||||
func DenoRequested(configuredBuild string) bool {
|
||||
if truthyEnv(core.Env("DENO_ENABLE")) {
|
||||
return true
|
||||
}
|
||||
|
||||
if core.Trim(core.Env("DENO_BUILD")) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return core.Trim(configuredBuild) != ""
|
||||
}
|
||||
|
||||
func truthyEnv(value string) bool {
|
||||
switch core.Lower(core.Trim(value)) {
|
||||
case "1", "true", "yes", "on":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ jobs:
|
|||
python -m pip install mkdocs
|
||||
|
||||
- name: Setup Deno
|
||||
if: hashFiles(format('{0}/**/deno.json', inputs.working-directory), format('{0}/**/deno.jsonc', inputs.working-directory)) != ''
|
||||
if: env.DENO_ENABLE == 'true' || env.DENO_ENABLE == '1' || env.DENO_ENABLE == 'yes' || env.DENO_ENABLE == 'on' || inputs.deno-build != '' || hashFiles(format('{0}/**/deno.json', inputs.working-directory), format('{0}/**/deno.jsonc', inputs.working-directory)) != ''
|
||||
uses: denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ func TestWorkflow_WriteReleaseWorkflow_Good(t *testing.T) {
|
|||
assert.Contains(t, content, "python -m pip install mkdocs")
|
||||
assert.Contains(t, content, "Setup Deno")
|
||||
assert.Contains(t, content, "denoland/setup-deno@v2")
|
||||
assert.Contains(t, content, "env.DENO_ENABLE == 'true'")
|
||||
assert.Contains(t, content, "inputs.deno-build != ''")
|
||||
assert.Contains(t, content, "build-cache:")
|
||||
assert.Contains(t, content, "Restore build cache")
|
||||
assert.Contains(t, content, "actions/cache@v4")
|
||||
|
|
|
|||
|
|
@ -147,6 +147,16 @@ set -euo pipefail
|
|||
|
||||
export PATH="${HOME}/go/bin:${HOME}/.deno/bin:${HOME}/.bun/bin:${PATH}"
|
||||
|
||||
deno_requested() {
|
||||
case "${DENO_ENABLE:-}" in
|
||||
1|true|TRUE|yes|YES|on|ON)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "${DENO_BUILD:-}" ]
|
||||
}
|
||||
|
||||
install_node_package_dir() {
|
||||
local dir="$1"
|
||||
if [ ! -f "$dir/package.json" ]; then
|
||||
|
|
@ -204,7 +214,7 @@ if ! command -v wails3 >/dev/null 2>&1 && ! command -v wails >/dev/null 2>&1; th
|
|||
go install github.com/wailsapp/wails/v3/cmd/wails3@latest
|
||||
fi
|
||||
|
||||
if find . -maxdepth 3 \( -name deno.json -o -name deno.jsonc \) -not -path '*/node_modules/*' | grep -q .; then
|
||||
if deno_requested || find . -maxdepth 3 \( -name deno.json -o -name deno.jsonc \) -not -path '*/node_modules/*' | grep -q .; then
|
||||
if ! command -v deno >/dev/null 2>&1; then
|
||||
curl -fsSL https://deno.land/install.sh | sh
|
||||
export PATH="${HOME}/.deno/bin:${PATH}"
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ func TestXcodeCloud_GenerateXcodeCloudScripts_Good(t *testing.T) {
|
|||
require.Len(t, scripts, 3)
|
||||
assert.Contains(t, scripts[XcodeCloudPostCloneScriptName], "go install github.com/wailsapp/wails/v3/cmd/wails3@latest")
|
||||
assert.Contains(t, scripts[XcodeCloudPostCloneScriptName], "find . -maxdepth 3 -name package.json")
|
||||
assert.Contains(t, scripts[XcodeCloudPostCloneScriptName], "deno_requested()")
|
||||
assert.Contains(t, scripts[XcodeCloudPostCloneScriptName], "DENO_ENABLE")
|
||||
assert.Contains(t, scripts[XcodeCloudPostCloneScriptName], "DENO_BUILD")
|
||||
assert.Contains(t, scripts[XcodeCloudPreXcodebuildScriptName], `core build apple --arch "universal" --config ".core/build.yaml" --notarise=false --dmg --appstore --bundle-id "ai.lthn.core" --team-id "ABC123DEF4"`)
|
||||
assert.Contains(t, scripts[XcodeCloudPostXcodebuildScriptName], `BUNDLE_PATH="dist/apple/Core.app"`)
|
||||
assert.Contains(t, scripts[XcodeCloudPostXcodebuildScriptName], "codesign --verify --deep --strict")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue