From 5d5d56c560f617dfcc2e4cfa6cb02e93098f887f Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Thu, 21 Aug 2025 23:57:58 -0400 Subject: [PATCH] refactor: remove public exposure of DOKKU_APP_TYPE in favor of builder detected property The DOKKU_APP_TYPE has long since ceased to be the correct way to specify the builder for the application. It's only usage has been during the detection phase, specifically to ensure that the herokuish plugin injects the correct docker arguments during the build. As such, it is safe to migrate away to a property in a patch release. Users that seek to set a specific builder should use 'dokku builder:set $APP selected' instead. Refs #7863 --- docs/configuration/environment-variables.md | 1 - plugins/builder-herokuish/docker-args-build | 6 ++-- plugins/builder/Makefile | 2 +- plugins/builder/builder.go | 1 + plugins/builder/report.go | 5 +++ plugins/builder/src/triggers/triggers.go | 5 +++ plugins/builder/subcommands.go | 5 +++ plugins/builder/triggers.go | 38 +++++++++++++++++++-- plugins/common/functions | 2 +- tests/unit/build-env.bats | 2 +- 10 files changed, 57 insertions(+), 10 deletions(-) diff --git a/docs/configuration/environment-variables.md b/docs/configuration/environment-variables.md index 69da15c2d..f4051cc89 100644 --- a/docs/configuration/environment-variables.md +++ b/docs/configuration/environment-variables.md @@ -101,7 +101,6 @@ The following config variables have special meanings and can be set in a variety | `DOKKU_APP_PROXY_TYPE` | `nginx` | `dokku proxy:set` | | | `DOKKU_APP_RESTORE` | `1` | `dokku config:set`
`dokku ps:stop` | | | `DOKKU_APP_SHELL` | `/bin/bash` | `dokku config:set` | Allows users to change the default shell used by Dokku for `dokku enter` and execution of deployment tasks. | -| `DOKKU_APP_TYPE` | `herokuish` | Auto-detected by using buildpacks or dockerfile | | | `DOKKU_CHECKS_DISABLED` | none | `dokku checks:disable` | | | `DOKKU_CHECKS_ENABLED` | none | `dokku checks:enable` | | | `DOKKU_CHECKS_SKIPPED` | none | `dokku checks:skip` | | diff --git a/plugins/builder-herokuish/docker-args-build b/plugins/builder-herokuish/docker-args-build index b720e1def..3ce6494f8 100755 --- a/plugins/builder-herokuish/docker-args-build +++ b/plugins/builder-herokuish/docker-args-build @@ -10,9 +10,9 @@ trigger-builder-herokuish-docker-args() { local STDIN DOKKU_APP_TYPE DOKKU_APP_USER STDIN=$(cat) - DOKKU_APP_TYPE=$(config_get "$APP" DOKKU_APP_TYPE || true) - DOKKU_APP_USER=$(config_get "$APP" DOKKU_APP_USER || true) - DOKKU_APP_USER=${DOKKU_APP_USER:="herokuishuser"} + DOKKU_APP_TYPE="$(plugn trigger builder-get-property "$APP" "detected" || true)" + DOKKU_APP_USER="$(config_get "$APP" DOKKU_APP_USER || true)" + DOKKU_APP_USER="${DOKKU_APP_USER:="herokuishuser"}" if [[ "$DOKKU_APP_TYPE" == "herokuish" ]]; then local docker_args="$STDIN --env=USER=${DOKKU_APP_USER}" diff --git a/plugins/builder/Makefile b/plugins/builder/Makefile index ff473113e..1b2969ea0 100644 --- a/plugins/builder/Makefile +++ b/plugins/builder/Makefile @@ -1,5 +1,5 @@ SUBCOMMANDS = subcommands/report subcommands/set -TRIGGERS = triggers/builder-detect triggers/builder-get-property triggers/builder-image-is-cnb triggers/builder-image-is-herokuish triggers/core-post-extract triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report +TRIGGERS = triggers/builder-detect triggers/builder-get-property triggers/builder-image-is-cnb triggers/builder-image-is-herokuish triggers/builder-set-property triggers/core-post-extract triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/report BUILD = commands subcommands triggers PLUGIN_NAME = builder diff --git a/plugins/builder/builder.go b/plugins/builder/builder.go index d4c390772..928d1a01c 100644 --- a/plugins/builder/builder.go +++ b/plugins/builder/builder.go @@ -4,6 +4,7 @@ var ( // DefaultProperties is a map of all valid builder properties with corresponding default property values DefaultProperties = map[string]string{ "selected": "", + "detected": "", "build-dir": "", } diff --git a/plugins/builder/report.go b/plugins/builder/report.go index 0d7772047..3a755d01e 100644 --- a/plugins/builder/report.go +++ b/plugins/builder/report.go @@ -14,6 +14,7 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { "--builder-computed-selected": reportComputedSelected, "--builder-global-selected": reportGlobalSelected, "--builder-selected": reportSelected, + "--builder-detected": reportDetected, "--builder-computed-build-dir": reportComputedBuildDir, "--builder-global-build-dir": reportGlobalBuildDir, "--builder-build-dir": reportBuildDir, @@ -43,6 +44,10 @@ func reportGlobalSelected(appName string) string { return common.PropertyGet("builder", "--global", "selected") } +func reportDetected(appName string) string { + return common.PropertyGet("builder", appName, "detected") +} + func reportSelected(appName string) string { return common.PropertyGet("builder", appName, "selected") } diff --git a/plugins/builder/src/triggers/triggers.go b/plugins/builder/src/triggers/triggers.go index 9fd5ce538..5490e74a8 100644 --- a/plugins/builder/src/triggers/triggers.go +++ b/plugins/builder/src/triggers/triggers.go @@ -33,6 +33,11 @@ func main() { appName := flag.Arg(0) image := flag.Arg(1) err = builder.TriggerBuilderImageIsHerokuish(appName, image) + case "builder-set-property": + appName := flag.Arg(0) + property := flag.Arg(1) + value := flag.Arg(2) + err = builder.TriggerBuilderSetProperty(appName, property, value) case "core-post-extract": appName := flag.Arg(0) sourceWorkDir := flag.Arg(1) diff --git a/plugins/builder/subcommands.go b/plugins/builder/subcommands.go index ad6e1081a..049c8327e 100644 --- a/plugins/builder/subcommands.go +++ b/plugins/builder/subcommands.go @@ -30,6 +30,11 @@ func CommandReport(appName string, format string, infoFlag string) error { // CommandSet set or clear a builder property for an app func CommandSet(appName string, property string, value string) error { + if property == "detected" { + common.LogWarn("detected is a read-only property") + return nil + } + common.CommandPropertySet("builder", appName, property, value, DefaultProperties, GlobalProperties) return nil } diff --git a/plugins/builder/triggers.go b/plugins/builder/triggers.go index 50e380994..dfbd57683 100644 --- a/plugins/builder/triggers.go +++ b/plugins/builder/triggers.go @@ -27,14 +27,23 @@ func TriggerBuilderDetect(appName string) error { // TriggerBuilderGetProperty writes the builder key to stdout for a given app container func TriggerBuilderGetProperty(appName string, key string) error { - if key != "selected" && key != "build-dir" { - return errors.New("Invalid logs property specified") + if _, ok := DefaultProperties[key]; !ok { + return errors.New("Invalid builder property specified") } fmt.Println(common.PropertyGet("builder", appName, key)) return nil } +// TriggerBuilderSetProperty writes the builder key to stdout for a given app container +func TriggerBuilderSetProperty(appName string, key string, value string) error { + if _, ok := DefaultProperties[key]; !ok { + return errors.New("Invalid builder property specified") + } + + return common.PropertyWrite("builder", appName, key, value) +} + // TriggerBuilderImageIsCNB prints true if an image is cnb based, false otherwise func TriggerBuilderImageIsCNB(appName string, image string) error { if common.IsImageCnbBased(image) { @@ -99,7 +108,30 @@ func TriggerInstall() error { return fmt.Errorf("Unable to install the builder plugin: %s", err.Error()) } - _, err := common.CallPlugnTrigger(common.PlugnTriggerInput{ + apps, err := common.UnfilteredDokkuApps() + if err != nil { + return nil + } + + for _, appName := range apps { + if common.PropertyExists("builder", appName, "detected") { + continue + } + + results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{ + Trigger: "config-get", + Args: []string{appName, "DOKKU_APP_TYPE"}, + }) + if err != nil { + return err + } + + if results.StdoutContents() != "" { + common.PropertyWrite("builder", appName, "detected", results.StdoutContents()) + } + } + + _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{ Trigger: "install-builder-prune", }) diff --git a/plugins/common/functions b/plugins/common/functions index f98068aac..ea1dcfe06 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -670,7 +670,7 @@ dokku_receive() { IMAGE_SOURCE_TYPE="pack" fi - DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_APP_TYPE="$IMAGE_SOURCE_TYPE" + plugn trigger builder-set-property "$APP" "detected" "$IMAGE_SOURCE_TYPE" if ! dokku_build "$APP" "$IMAGE_SOURCE_TYPE" "$TMP_WORK_DIR"; then return 1 fi diff --git a/tests/unit/build-env.bats b/tests/unit/build-env.bats index dd83f1e36..3f5e87ff8 100644 --- a/tests/unit/build-env.bats +++ b/tests/unit/build-env.bats @@ -75,7 +75,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku --quiet config:get $TEST_APP DOKKU_APP_TYPE" + run /bin/bash -c "dokku builder:report $TEST_APP --builder-detected" echo "output: $output" echo "status: $status" assert_output "herokuish"