diff --git a/cmd/forgejo/actions.go b/cmd/forgejo/actions.go
index 1262a02584..0da9130505 100644
--- a/cmd/forgejo/actions.go
+++ b/cmd/forgejo/actions.go
@@ -7,6 +7,7 @@ import (
 	"context"
 	"fmt"
 
+	actions_model "code.gitea.io/gitea/models/actions"
 	"code.gitea.io/gitea/modules/private"
 	"code.gitea.io/gitea/modules/setting"
 
@@ -18,12 +19,13 @@ func CmdActions(ctx context.Context) cli.Command {
 		Name:  "actions",
 		Usage: "Commands for managing Forgejo Actions",
 		Subcommands: []cli.Command{
-			SubcmdActionsGenRunnerToken(ctx),
+			SubcmdActionsGenerateRunnerToken(ctx),
+			SubcmdActionsGenerateRunnerSecret(ctx),
 		},
 	}
 }
 
-func SubcmdActionsGenRunnerToken(ctx context.Context) cli.Command {
+func SubcmdActionsGenerateRunnerToken(ctx context.Context) cli.Command {
 	return cli.Command{
 		Name:   "generate-runner-token",
 		Usage:  "Generate a new token for a runner to use to register with the server",
@@ -38,8 +40,29 @@ func SubcmdActionsGenRunnerToken(ctx context.Context) cli.Command {
 	}
 }
 
+func SubcmdActionsGenerateRunnerSecret(ctx context.Context) cli.Command {
+	return cli.Command{
+		Name:   "generate-secret",
+		Usage:  "Generate a secret suitable for input to the register subcommand",
+		Action: func(cliCtx *cli.Context) error { return RunGenerateSecret(ctx, cliCtx) },
+	}
+}
+
+func RunGenerateSecret(ctx context.Context, cliCtx *cli.Context) error {
+	setting.MustInstalled()
+
+	runner := actions_model.ActionRunner{}
+	if err := runner.GenerateToken(); err != nil {
+		return err
+	}
+	if _, err := fmt.Fprintf(ContextGetStdout(ctx), "%s", runner.Token); err != nil {
+		panic(err)
+	}
+	return nil
+}
+
 func RunGenerateActionsRunnerToken(ctx context.Context, cliCtx *cli.Context) error {
-	if !ContextGetNoInstallSignals(ctx) {
+	if !ContextGetNoInit(ctx) {
 		var cancel context.CancelFunc
 		ctx, cancel = installSignals(ctx)
 		defer cancel()
diff --git a/tests/integration/cmd_forgejo_actions_test.go b/tests/integration/cmd_forgejo_actions_test.go
index 9767d03675..e2fbb77dae 100644
--- a/tests/integration/cmd_forgejo_actions_test.go
+++ b/tests/integration/cmd_forgejo_actions_test.go
@@ -16,7 +16,12 @@ func Test_CmdForgejo_Actions(t *testing.T) {
 	onGiteaRun(t, func(*testing.T, *url.URL) {
 		defer test.MockVariable(&setting.Actions.Enabled, true)()
 
-		output := cmdForgejoCaptureOutput(t, []string{"forgejo-cli", "actions", "generate-runner-token"})
+		var output string
+
+		output = cmdForgejoCaptureOutput(t, []string{"forgejo-cli", "actions", "generate-runner-token"})
+		assert.EqualValues(t, 40, len(output))
+
+		output = cmdForgejoCaptureOutput(t, []string{"forgejo-cli", "actions", "generate-secret"})
 		assert.EqualValues(t, 40, len(output))
 	})
 }