From af18e583ac2eccb1eea8b398ec768ab35196a188 Mon Sep 17 00:00:00 2001 From: Hendrik Brombeer Date: Tue, 5 May 2026 08:23:57 +0200 Subject: [PATCH] feat(push): --force flag to skip forge contentHash dedup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Threads a new `--force` flag through to the Gradle invocation, which in turn appends `?force=true` to forge's POST /v1/pushes call. Skips the contentHash idempotency lookup so the build pipeline runs even when an identical push already produced an image — useful when the upstream base image moved under a stable tag. Pairs with grounds-push#TBD and grounds-forge#TBD. Co-Authored-By: Claude Opus 4.7 (1M context) --- cmd/grounds/commands/push/push.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cmd/grounds/commands/push/push.go b/cmd/grounds/commands/push/push.go index 9d31ba3..c65ad1b 100644 --- a/cmd/grounds/commands/push/push.go +++ b/cmd/grounds/commands/push/push.go @@ -24,16 +24,21 @@ func NewPushCommand() *cobra.Command { func newPush() *cobra.Command { var target string + var force bool cmd := &cobra.Command{ - Use: "push [--target=dev|staging]", + Use: "push [--target=dev|staging] [--force]", Short: "Build via Gradle plugin and deploy to a target", - Example: " grounds push\n grounds push --target=staging", + Example: " grounds push\n grounds push --target=staging\n grounds push --force", Long: `Build the current project with the grounds-push Gradle plugin and deploy it. Targets: dev — long-lived, lands in your personal namespace (user-). staging — ephemeral preview env, fresh namespace per push, auto-deleted after 7 days. - Public URL pattern: -pr.dev.grnds.io.`, + Public URL pattern: -pr.dev.grnds.io. + +--force re-runs the build pipeline even when forge's contentHash dedup +would have reused an existing image. Useful when the upstream base +image moved under a stable tag, or to re-observe the build flow.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { if target != "dev" && target != "staging" { @@ -70,6 +75,9 @@ Targets: } args := []string{"groundsPush", "--target=" + target} + if force { + args = append(args, "--force") + } return gradle.Run(ctx, wrapper, args, cmd.OutOrStdout(), cmd.ErrOrStderr(), 0) }, } @@ -77,6 +85,7 @@ Targets: _ = cmd.RegisterFlagCompletionFunc("target", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) { return []string{"dev", "staging"}, cobra.ShellCompDirectiveNoFileComp }) + cmd.Flags().BoolVar(&force, "force", false, "skip contentHash dedup and force a fresh build") return cmd }