From 293dfd6e66cee79a4bb43d1a67355c26ca377d25 Mon Sep 17 00:00:00 2001 From: Snider Date: Tue, 14 Apr 2026 21:35:50 +0100 Subject: [PATCH] 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 --- cmd/build/cmd_workflow_test.go | 4 ++ pkg/api/provider.go | 10 ++++ pkg/api/provider_test.go | 12 +++++ pkg/build/apple.go | 24 ++++++++-- pkg/build/apple_test.go | 58 +++++++++++++++++++++++ pkg/build/builders/node.go | 7 ++- pkg/build/builders/node_test.go | 79 ++++++++++++++++++++++++++++++++ pkg/build/builders/wails.go | 19 +++++++- pkg/build/builders/wails_test.go | 73 +++++++++++++++++++++++++++++ pkg/build/discovery.go | 34 ++++++++++++++ pkg/build/discovery_test.go | 20 ++++++++ pkg/build/env.go | 26 +++++++++++ pkg/build/templates/release.yml | 2 +- pkg/build/workflow_test.go | 2 + pkg/build/xcode_cloud.go | 12 ++++- pkg/build/xcode_cloud_test.go | 3 ++ 16 files changed, 377 insertions(+), 8 deletions(-) diff --git a/cmd/build/cmd_workflow_test.go b/cmd/build/cmd_workflow_test.go index 7002f29..7561c90 100644 --- a/cmd/build/cmd_workflow_test.go +++ b/cmd/build/cmd_workflow_test.go @@ -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") diff --git a/pkg/api/provider.go b/pkg/api/provider.go index b548014..419eca4 100644 --- a/pkg/api/provider.go +++ b/pkg/api/provider.go @@ -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, diff --git a/pkg/api/provider_test.go b/pkg/api/provider_test.go index f5bf161..18e6334 100644 --- a/pkg/api/provider_test.go +++ b/pkg/api/provider_test.go @@ -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`) diff --git a/pkg/build/apple.go b/pkg/build/apple.go index 101d696..ea6a8ae 100644 --- a/pkg/build/apple.go +++ b/pkg/build/apple.go @@ -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 { diff --git a/pkg/build/apple_test.go b/pkg/build/apple_test.go index 4001cac..0a743f9 100644 --- a/pkg/build/apple_test.go +++ b/pkg/build/apple_test.go @@ -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") diff --git a/pkg/build/builders/node.go b/pkg/build/builders/node.go index 3f06f18..0d605de 100644 --- a/pkg/build/builders/node.go +++ b/pkg/build/builders/node.go @@ -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) } diff --git a/pkg/build/builders/node_test.go b/pkg/build/builders/node_test.go index 065a2dc..2c88a41 100644 --- a/pkg/build/builders/node_test.go +++ b/pkg/build/builders/node_test.go @@ -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() diff --git a/pkg/build/builders/wails.go b/pkg/build/builders/wails.go index c567155..28bd5a8 100644 --- a/pkg/build/builders/wails.go +++ b/pkg/build/builders/wails.go @@ -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 "" } diff --git a/pkg/build/builders/wails_test.go b/pkg/build/builders/wails_test.go index 0baf1e2..dc95581 100644 --- a/pkg/build/builders/wails_test.go +++ b/pkg/build/builders/wails_test.go @@ -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") diff --git a/pkg/build/discovery.go b/pkg/build/discovery.go index 66ddce9..ff97e4a 100644 --- a/pkg/build/discovery.go +++ b/pkg/build/discovery.go @@ -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 { diff --git a/pkg/build/discovery_test.go b/pkg/build/discovery_test.go index c9a0455..8575f63 100644 --- a/pkg/build/discovery_test.go +++ b/pkg/build/discovery_test.go @@ -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) diff --git a/pkg/build/env.go b/pkg/build/env.go index 50300bd..095c862 100644 --- a/pkg/build/env.go +++ b/pkg/build/env.go @@ -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 + } +} diff --git a/pkg/build/templates/release.yml b/pkg/build/templates/release.yml index af16ba3..75c3ff1 100644 --- a/pkg/build/templates/release.yml +++ b/pkg/build/templates/release.yml @@ -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 diff --git a/pkg/build/workflow_test.go b/pkg/build/workflow_test.go index 6ae3d15..8420090 100644 --- a/pkg/build/workflow_test.go +++ b/pkg/build/workflow_test.go @@ -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") diff --git a/pkg/build/xcode_cloud.go b/pkg/build/xcode_cloud.go index 401421e..0cf2e32 100644 --- a/pkg/build/xcode_cloud.go +++ b/pkg/build/xcode_cloud.go @@ -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}" diff --git a/pkg/build/xcode_cloud_test.go b/pkg/build/xcode_cloud_test.go index 5ff8fba..c924538 100644 --- a/pkg/build/xcode_cloud_test.go +++ b/pkg/build/xcode_cloud_test.go @@ -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")