From 19b28a86e73bd1da15a7f87fd764b4a0a05d8194 Mon Sep 17 00:00:00 2001 From: Hendrik Brombeer Date: Wed, 29 Apr 2026 18:56:51 +0200 Subject: [PATCH] fix(push): pre-refresh access token before invoking Gradle plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Gradle plugin reads credentials.json directly via CredentialResolver and rejects expired access tokens — without ever calling the OIDC refresh endpoint. Keycloak's default access-token lifetime is ~5min, so users had to re-run 'grounds login' between every push attempt that took longer than that to set up. Wire the CLI's existing FileTokenSource.Token() in front of the gradle.Run() call: it transparently refreshes the access token (using the still-valid refresh token) and persists the new credentials to disk before Gradle reads the file. Skip the pre-refresh when GROUNDS_TOKEN is set — the plugin uses the env var directly via Credentials.FromEnv, bypassing the file. Reported by lusu007: 'läuft gefühlt alle 5min ab'. --- cmd/grounds/commands/push/push.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cmd/grounds/commands/push/push.go b/cmd/grounds/commands/push/push.go index c8491e0..48b924c 100644 --- a/cmd/grounds/commands/push/push.go +++ b/cmd/grounds/commands/push/push.go @@ -10,6 +10,7 @@ import ( "github.com/spf13/cobra" "github.com/groundsgg/grounds-cli/internal/auth" + "github.com/groundsgg/grounds-cli/internal/config" "github.com/groundsgg/grounds-cli/internal/gradle" ) @@ -43,6 +44,27 @@ Targets: return fmt.Errorf("%w\n → not a Gradle project? Run 'grounds init' to scaffold, or cd to your project root", err) } ctx := context.Background() + + // Pre-refresh: the Gradle plugin reads credentials.json + // directly via CredentialResolver and rejects expired + // access tokens (Keycloak default lifetime is ~5min). + // Force a refresh here so the file is fresh before + // Gradle reads it. Skip when GROUNDS_TOKEN is set — + // the plugin uses the env var directly, no file involved. + if os.Getenv("GROUNDS_TOKEN") == "" { + cfg, err := config.Load("") + if err != nil { + return err + } + src := &auth.FileTokenSource{ + Store: auth.NewStore(cfg.Dir), + Device: defaultDevice(), + } + if _, err := src.Token(ctx); err != nil { + return fmt.Errorf("auth refresh failed: %w\n → run 'grounds login' to re-authenticate", err) + } + } + args := []string{"groundsPush", "--target=" + target} return gradle.Run(ctx, wrapper, args, cmd.OutOrStdout(), cmd.ErrOrStderr(), 0) },