From fc2b49e57163d504ba209f5abf29745c61f5cc84 Mon Sep 17 00:00:00 2001
From: Earl Warren <contact@earl-warren.org>
Date: Thu, 9 Mar 2023 10:56:38 +0100
Subject: [PATCH] [ACTIONS] forgejo actions --registration-token-admin

(cherry picked from commit 481d813539762af6670b2cb4d3e893ab27dfe544)

address oliverpool comments

(cherry picked from commit d8f313f9e21ceea7b113fc04938fa4ffea577d9e)

s/Printf/Print/

(cherry picked from commit 6621b04458b9fbaf8b6664efd86886b2ebbec01d)

do not run initDB within integration tests

(cherry picked from commit 5a0428ede3e8f242860d121ab3ee8712a1fe2f14)
(cherry picked from commit e8287b753d70d51e9bec23e732d797fe900a4911)
---
 cmd/actions.go                        | 68 +++++++++++++++++++++++++++
 main.go                               |  1 +
 tests/integration/cmd_actions_test.go | 50 ++++++++++++++++++++
 3 files changed, 119 insertions(+)
 create mode 100644 cmd/actions.go
 create mode 100644 tests/integration/cmd_actions_test.go

diff --git a/cmd/actions.go b/cmd/actions.go
new file mode 100644
index 0000000000..7a3bb7f226
--- /dev/null
+++ b/cmd/actions.go
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: MIT
+
+package cmd
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"log"
+
+	actions_model "code.gitea.io/gitea/models/actions"
+	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/util"
+
+	"github.com/urfave/cli"
+)
+
+// CmdActions represents the available actions sub-command.
+var CmdActions = cli.Command{
+	Name:        "actions",
+	Usage:       "Actions",
+	Description: "Actions",
+	Action:      runActions,
+	Flags: []cli.Flag{
+		cli.BoolFlag{
+			Name:  "registration-token-admin",
+			Usage: "Show the runner registration admin token",
+		},
+	},
+}
+
+func maybeInitDB(stdCtx context.Context) error {
+	if setting.Database.Type == "" {
+		if err := initDB(stdCtx); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func runActions(ctx *cli.Context) error {
+	stdCtx := context.Background()
+
+	if err := maybeInitDB(stdCtx); err != nil {
+		log.Fatalf("maybeInitDB %v", err)
+	}
+
+	if ctx.Bool("registration-token-admin") {
+		// ownid=0,repo_id=0,means this token is used for global
+		return runActionsRegistrationToken(stdCtx, 0, 0)
+	}
+	return nil
+}
+
+func runActionsRegistrationToken(stdCtx context.Context, ownerID, repoID int64) error {
+	var token *actions_model.ActionRunnerToken
+	token, err := actions_model.GetUnactivatedRunnerToken(stdCtx, ownerID, repoID)
+	if errors.Is(err, util.ErrNotExist) {
+		token, err = actions_model.NewRunnerToken(stdCtx, ownerID, repoID)
+		if err != nil {
+			log.Fatalf("CreateRunnerToken %v", err)
+		}
+	} else if err != nil {
+		log.Fatalf("GetUnactivatedRunnerToken %v", err)
+	}
+	fmt.Print(token.Token)
+	return nil
+}
diff --git a/main.go b/main.go
index eeedf54c27..f004d58bea 100644
--- a/main.go
+++ b/main.go
@@ -58,6 +58,7 @@ func main() {
 arguments - which can alternatively be run by running the subcommand web.`
 	app.Version = Version + formatBuiltWith()
 	app.Commands = []cli.Command{
+		cmd.CmdActions,
 		cmd.CmdWeb,
 		cmd.CmdServ,
 		cmd.CmdHook,
diff --git a/tests/integration/cmd_actions_test.go b/tests/integration/cmd_actions_test.go
new file mode 100644
index 0000000000..6b74d31628
--- /dev/null
+++ b/tests/integration/cmd_actions_test.go
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+	"bytes"
+	"flag"
+	"io"
+	"net/url"
+	"os"
+	"testing"
+
+	"code.gitea.io/gitea/cmd"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/urfave/cli"
+)
+
+func Test_CmdActions(t *testing.T) {
+	onGiteaRun(t, func(*testing.T, *url.URL) {
+		tests := []struct {
+			name           string
+			args           []string
+			wantErr        bool
+			expectedOutput func(string)
+		}{
+			{"test_registration-token-admin", []string{"actions", "--registration-token-admin"}, false, func(output string) { assert.EqualValues(t, 40, len(output), output) }},
+		}
+		for _, tt := range tests {
+			t.Run(tt.name, func(t *testing.T) {
+				realStdout := os.Stdout
+				r, w, _ := os.Pipe()
+				os.Stdout = w
+
+				set := flag.NewFlagSet("actions", 0)
+				_ = set.Parse(tt.args)
+				context := cli.NewContext(&cli.App{Writer: os.Stdout}, set, nil)
+				err := cmd.CmdActions.Run(context)
+				if (err != nil) != tt.wantErr {
+					t.Errorf("CmdActions.Run() error = %v, wantErr %v", err, tt.wantErr)
+				}
+				w.Close()
+				var buf bytes.Buffer
+				io.Copy(&buf, r)
+				tt.expectedOutput(buf.String())
+				os.Stdout = realStdout
+			})
+		}
+	})
+}