Skip to content

Commit 73c7fa9

Browse files
author
Ole Martin Handeland
committed
Adding --dev-frontend to studioctl build as well, and using those when running github workflows
1 parent d5cd5db commit 73c7fa9

8 files changed

Lines changed: 119 additions & 3 deletions

File tree

.github/actions/app-run-local-env/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ runs:
121121
}
122122
123123
function targetRunArgs(path, image) {
124-
const args = ['run', '--mode', 'container', '--detach', '--random-host-port', '--path', path];
124+
const args = ['run', '--mode', 'container', '--detach', '--random-host-port', '--dev-frontend', '--path', path];
125125
if (image) {
126126
args.push('--image-tag', image, '--pull', '--skip-build');
127127
}

.github/workflows/app-frontend-cypress.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ jobs:
100100
while (nextTarget < targets.length) {
101101
const target = targets[nextTarget++];
102102
core.info(`Worker ${workerId}: building ${target.path}`);
103-
await exec.exec('studioctl', ['app', 'build', '--path', target.path, '--image-tag', target.image, '--push']);
103+
await exec.exec('studioctl', ['app', 'build', '--path', target.path, '--image-tag', target.image, '--push', '--dev-frontend']);
104104
}
105105
}
106106

src/cli/internal/appimage/spec.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,30 @@ type BuildSpec struct {
3535
Build types.BuildOptions
3636
}
3737

38+
// SetAppFrontendAssetBaseURL injects a frontend asset base URL into the built app image.
39+
func SetAppFrontendAssetBaseURL(spec *BuildSpec, value string) error {
40+
if value == "" {
41+
return nil
42+
}
43+
44+
content := spec.DockerfileContent
45+
if content == "" {
46+
data, err := os.ReadFile(spec.Dockerfile)
47+
if err != nil {
48+
return fmt.Errorf("read dockerfile: %w", err)
49+
}
50+
content = string(data)
51+
}
52+
53+
if !strings.HasSuffix(content, "\n") {
54+
content += "\n"
55+
}
56+
content += "ENV AppSettings__AppFrontendAssetBaseUrl=" + value + "\n"
57+
spec.Dockerfile = ""
58+
spec.DockerfileContent = content
59+
return nil
60+
}
61+
3862
// BuildSpecForApp builds image build configuration for an app container.
3963
func BuildSpecForApp(result repocontext.Detection, imageTag string) (BuildSpec, error) {
4064
runRepo, err := newRepoContext(result)

src/cli/internal/appimage/spec_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,38 @@ func TestBuildSpecForApp_StandaloneAppInjectsConfigCopy(t *testing.T) {
242242
assertInOrder(t, spec.DockerfileContent, []string{publish, copyConfig, final})
243243
}
244244

245+
func TestSetAppFrontendAssetBaseURL_AppendsEnvToFinalStage(t *testing.T) {
246+
t.Parallel()
247+
248+
appRoot := t.TempDir()
249+
writeTestAppDockerfile(t, appRoot, "Altinn.Application.dll")
250+
251+
spec, err := appimage.BuildSpecForApp(repocontext.Detection{
252+
AppRoot: appRoot,
253+
InAppRepo: true,
254+
}, "")
255+
if err != nil {
256+
t.Fatalf("BuildSpecForApp() error = %v", err)
257+
}
258+
259+
want := "http://app-frontend.local.altinn.cloud:8000"
260+
if err := appimage.SetAppFrontendAssetBaseURL(&spec, want); err != nil {
261+
t.Fatalf("SetAppFrontendAssetBaseURL() error = %v", err)
262+
}
263+
264+
if spec.Dockerfile != "" {
265+
t.Fatalf("Dockerfile = %q, want generated dockerfile", spec.Dockerfile)
266+
}
267+
assertContainsAll(t, spec.DockerfileContent, []string{
268+
"ENV AppSettings__AppFrontendAssetBaseUrl=" + want,
269+
})
270+
assertInOrder(t, spec.DockerfileContent, []string{
271+
"FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine AS final",
272+
`ENTRYPOINT ["dotnet","Altinn.Application.dll"]`,
273+
"ENV AppSettings__AppFrontendAssetBaseUrl=" + want,
274+
})
275+
}
276+
245277
func TestBuildSpecForApp_StandaloneAppDoesNotDuplicateExistingConfigCopy(t *testing.T) {
246278
t.Parallel()
247279

src/cli/internal/cmd/app.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
appsvc "altinn.studio/studioctl/internal/cmd/app"
1717
"altinn.studio/studioctl/internal/config"
1818
repocontext "altinn.studio/studioctl/internal/context"
19+
"altinn.studio/studioctl/internal/envtopology"
1920
"altinn.studio/studioctl/internal/osutil"
2021
"altinn.studio/studioctl/internal/studio"
2122
"altinn.studio/studioctl/internal/studioctlserver"
@@ -48,6 +49,7 @@ type appBuildFlags struct {
4849
mode string
4950
imageTag string
5051
push bool
52+
devFrontend bool
5153
jsonOutput bool
5254
}
5355

@@ -167,6 +169,9 @@ func (c *AppCommand) runBuild(ctx context.Context, args []string) error {
167169
if err != nil {
168170
return fmt.Errorf("build docker image spec: %w", err)
169171
}
172+
if err := appimage.SetAppFrontendAssetBaseURL(&spec, appBuildFrontendAssetBaseURL(flags)); err != nil {
173+
return fmt.Errorf("set app frontend asset base URL: %w", err)
174+
}
170175
cleanupDockerfile, err := appimage.MaterializeDockerfile(&spec)
171176
if err != nil {
172177
return fmt.Errorf("materialize dockerfile: %w", err)
@@ -213,6 +218,7 @@ func (c *AppCommand) parseAppBuildFlags(args []string) (appBuildFlags, bool, err
213218
fs.StringVar(&flags.mode, "mode", runModeContainer, "Build mode")
214219
fs.StringVar(&flags.imageTag, "image-tag", "", "App container image tag")
215220
fs.BoolVar(&flags.push, "push", false, "Push app container image after build")
221+
fs.BoolVar(&flags.devFrontend, "dev-frontend", false, "Use frontend dev server assets")
216222
fs.BoolVar(&flags.jsonOutput, "json", false, "Output as JSON")
217223

218224
if err := fs.Parse(args); err != nil {
@@ -240,13 +246,22 @@ func (c *AppCommand) appBuildUsage() string {
240246
"Options:",
241247
" -p, --path PATH Specify app directory (overrides auto-detect)",
242248
" -m, --mode MODE Build mode: container (default: container)",
249+
" --dev-frontend Use frontend dev server assets",
243250
" --image-tag IMAGE App container image tag",
244251
" --push Push app container image after build",
245252
" --json Output as JSON",
246253
" -h, --help Show this help",
247254
)
248255
}
249256

257+
func appBuildFrontendAssetBaseURL(flags appBuildFlags) string {
258+
if !flags.devFrontend {
259+
return ""
260+
}
261+
topology := envtopology.NewLocal(envtopology.DefaultIngressPortString())
262+
return topology.PublicBaseURL(envtopology.ComponentFrontendDevServer)
263+
}
264+
250265
func (c *AppCommand) runUpdate(ctx context.Context, args []string) error {
251266
fs := flag.NewFlagSet("app update", flag.ContinueOnError)
252267
var appPath string
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package cmd
2+
3+
import (
4+
"io"
5+
"testing"
6+
7+
"altinn.studio/studioctl/internal/envtopology"
8+
"altinn.studio/studioctl/internal/ui"
9+
)
10+
11+
func TestParseAppBuildFlagsReadsDevFrontend(t *testing.T) {
12+
t.Parallel()
13+
14+
cmd := &AppCommand{out: ui.NewOutput(io.Discard, io.Discard, false)}
15+
flags, _, err := cmd.parseAppBuildFlags([]string{"--dev-frontend"})
16+
if err != nil {
17+
t.Fatalf("parseAppBuildFlags() error = %v", err)
18+
}
19+
if !flags.devFrontend {
20+
t.Fatal("devFrontend = false, want true")
21+
}
22+
}
23+
24+
func TestAppBuildFrontendAssetBaseURLUsesTopologyFrontendDevServer(t *testing.T) {
25+
t.Parallel()
26+
27+
got := appBuildFrontendAssetBaseURL(appBuildFlags{devFrontend: true})
28+
want := envtopology.NewLocal(envtopology.DefaultIngressPortString()).PublicBaseURL(envtopology.ComponentFrontendDevServer)
29+
if got != want {
30+
t.Fatalf("appBuildFrontendAssetBaseURL() = %q, want %q", got, want)
31+
}
32+
}

src/cli/internal/cmd/run.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,7 @@ func (c *RunCommand) runDocker(
12171217
ctx,
12181218
client,
12191219
result,
1220+
topology,
12201221
spec.Config.Image,
12211222
flags,
12221223
progress,
@@ -1439,6 +1440,7 @@ func (c *RunCommand) prepareDockerRunImage(
14391440
ctx context.Context,
14401441
client containerruntime.ContainerClient,
14411442
result repocontext.Detection,
1443+
topology envtopology.Local,
14421444
imageTag string,
14431445
flags runFlags,
14441446
progress *containerRunProgress,
@@ -1462,6 +1464,9 @@ func (c *RunCommand) prepareDockerRunImage(
14621464
if err != nil {
14631465
return fmt.Errorf("build docker image spec: %w", err)
14641466
}
1467+
if err := appimage.SetAppFrontendAssetBaseURL(&spec, runAppFrontendAssetBaseUrl(topology, flags)); err != nil {
1468+
return fmt.Errorf("set app frontend asset base URL: %w", err)
1469+
}
14651470
cleanupDockerfile, prepareErr := appimage.MaterializeDockerfile(&spec)
14661471
if prepareErr != nil {
14671472
return fmt.Errorf("materialize dockerfile: %w", prepareErr)

src/cli/internal/cmd/run_internal_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,15 @@ func TestPrepareDockerRunImagePullUsesProgressRenderer(t *testing.T) {
391391
return nil
392392
}
393393

394-
err := cmd.prepareDockerRunImage(t.Context(), client, repocontext.Detection{}, flags.imageTag, flags, progress)
394+
err := cmd.prepareDockerRunImage(
395+
t.Context(),
396+
client,
397+
repocontext.Detection{},
398+
envtopology.NewLocal(envtopology.DefaultIngressPortString()),
399+
flags.imageTag,
400+
flags,
401+
progress,
402+
)
395403
if err != nil {
396404
t.Fatalf("prepareDockerRunImage() error = %v", err)
397405
}

0 commit comments

Comments
 (0)