Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package semaphore for openSUSE:Factory checked in at 2026-06-05 15:01:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/semaphore (Old) and /work/SRC/openSUSE:Factory/.semaphore.new.2375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "semaphore" Fri Jun 5 15:01:06 2026 rev:47 rq:1357172 version:2.18.9 Changes: -------- --- /work/SRC/openSUSE:Factory/semaphore/semaphore.changes 2026-06-03 20:27:41.214314036 +0200 +++ /work/SRC/openSUSE:Factory/.semaphore.new.2375/semaphore.changes 2026-06-05 15:01:30.643310199 +0200 @@ -1,0 +2,6 @@ +Thu Jun 04 14:07:03 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 2.18.9: + * 0a37ea2 feat(cli): allow create token + +------------------------------------------------------------------- Old: ---- semaphore-2.18.8.obscpio web-2.18.8.tar.gz New: ---- semaphore-2.18.9.obscpio web-2.18.9.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ semaphore.spec ++++++ --- /var/tmp/diff_new_pack.hnGgb9/_old 2026-06-05 15:01:44.343876800 +0200 +++ /var/tmp/diff_new_pack.hnGgb9/_new 2026-06-05 15:01:44.351877130 +0200 @@ -17,7 +17,7 @@ Name: semaphore -Version: 2.18.8 +Version: 2.18.9 Release: 0 Summary: Modern UI for Ansible License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.hnGgb9/_old 2026-06-05 15:01:44.971902773 +0200 +++ /var/tmp/diff_new_pack.hnGgb9/_new 2026-06-05 15:01:44.995903768 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/ansible-semaphore/semaphore</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v2.18.8</param> + <param name="revision">v2.18.9</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.hnGgb9/_old 2026-06-05 15:01:45.203912387 +0200 +++ /var/tmp/diff_new_pack.hnGgb9/_new 2026-06-05 15:01:45.267915039 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/ansible-semaphore/semaphore</param> - <param name="changesrevision">459ccee8ee67b779fd87ba4309698f5296356703</param></service></servicedata> + <param name="changesrevision">0a37ea29f286c68b60bc80639363fa687eeac620</param></service></servicedata> (No newline at EOF) ++++++ semaphore-2.18.8.obscpio -> semaphore-2.18.9.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/semaphore-2.18.8/cli/cmd/token.go new/semaphore-2.18.9/cli/cmd/token.go --- old/semaphore-2.18.8/cli/cmd/token.go 2026-06-02 19:00:09.000000000 +0200 +++ new/semaphore-2.18.9/cli/cmd/token.go 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -package cmd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/semaphore-2.18.8/cli/cmd/user_token.go new/semaphore-2.18.9/cli/cmd/user_token.go --- old/semaphore-2.18.8/cli/cmd/user_token.go 1970-01-01 01:00:00.000000000 +0100 +++ new/semaphore-2.18.9/cli/cmd/user_token.go 2026-06-03 13:01:15.000000000 +0200 @@ -0,0 +1,134 @@ +package cmd + +import ( + "crypto/rand" + "encoding/base64" + "errors" + "fmt" + "io" + "os" + "strings" + "time" + + "github.com/semaphoreui/semaphore/db" + "github.com/semaphoreui/semaphore/pkg/tz" + "github.com/spf13/cobra" +) + +type tokenArgs struct { + login string + name string + ttl string +} + +var targetTokenArgs tokenArgs + +func init() { + tokenCreateCmd.PersistentFlags().StringVar(&targetTokenArgs.login, "login", "", "Login of the token owner") + tokenCreateCmd.PersistentFlags().StringVar(&targetTokenArgs.ttl, "ttl", "", "Token lifetime (e.g. 1h, 30m, 24h). Token never expires if omitted") + tokenCreateCmd.PersistentFlags().StringVar(&targetTokenArgs.name, "name", "", "Token name") + + tokenListCmd.PersistentFlags().StringVar(&targetTokenArgs.login, "login", "", "Login of the token owner") + + tokenCmd.AddCommand(tokenCreateCmd) + tokenCmd.AddCommand(tokenListCmd) + userCmd.AddCommand(tokenCmd) +} + +var tokenCmd = &cobra.Command{ + Use: "token", + Short: "Manage user API tokens", + Run: func(cmd *cobra.Command, args []string) { + _ = cmd.Help() + os.Exit(0) + }, +} + +func getTokenUser(store db.Store) db.User { + if targetTokenArgs.login == "" { + fmt.Println("Argument --login required") + os.Exit(1) + } + + user, err := store.GetUserByLoginOrEmail(targetTokenArgs.login, "") + if errors.Is(err, db.ErrNotFound) { + fmt.Printf("User with login %s not found\n", targetTokenArgs.login) + os.Exit(1) + } + if err != nil { + panic(err) + } + + return user +} + +var tokenCreateCmd = &cobra.Command{ + Use: "create", + Short: "Create new API token", + Run: func(cmd *cobra.Command, args []string) { + store := createStore("") + defer store.Close("") + + user := getTokenUser(store) + + var expiresAt *time.Time + if targetTokenArgs.ttl != "" { + d, err := time.ParseDuration(targetTokenArgs.ttl) + if err != nil { + fmt.Printf("Invalid --ttl value: %s\n", err) + os.Exit(1) + } + t := tz.Now().Add(d) + expiresAt = &t + } + + tokenID := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, tokenID); err != nil { + panic(err) + } + + token, err := store.CreateAPIToken(db.APIToken{ + ID: strings.ToLower(base64.URLEncoding.EncodeToString(tokenID)), + UserID: user.ID, + Expired: false, + ExpiresAt: expiresAt, + Name: targetTokenArgs.name, + }) + if err != nil { + panic(err) + } + + fmt.Println(token.ID) + }, +} + +var tokenListCmd = &cobra.Command{ + Use: "list", + Short: "List user API tokens", + Run: func(cmd *cobra.Command, args []string) { + store := createStore("") + defer store.Close("") + + user := getTokenUser(store) + + tokens, err := store.GetAPITokens(user.ID) + if err != nil && !errors.Is(err, db.ErrNotFound) { + panic(err) + } + + now := tz.Now() + for _, token := range tokens { + status := "active" + if token.IsExpiredAt(now) { + status = "expired" + } + + expires := "never" + if token.ExpiresAt != nil { + expires = token.ExpiresAt.Format(time.RFC3339) + } + + fmt.Printf("%s\t%s\t%s\n", token.Name, status, expires) + } + }, +} ++++++ semaphore.obsinfo ++++++ --- /var/tmp/diff_new_pack.hnGgb9/_old 2026-06-05 15:01:48.696057093 +0200 +++ /var/tmp/diff_new_pack.hnGgb9/_new 2026-06-05 15:01:48.728058419 +0200 @@ -1,5 +1,5 @@ name: semaphore -version: 2.18.8 -mtime: 1780419609 -commit: 459ccee8ee67b779fd87ba4309698f5296356703 +version: 2.18.9 +mtime: 1780484475 +commit: 0a37ea29f286c68b60bc80639363fa687eeac620 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/semaphore/vendor.tar.gz /work/SRC/openSUSE:Factory/.semaphore.new.2375/vendor.tar.gz differ: char 13, line 1 ++++++ web-2.18.8.tar.gz -> web-2.18.9.tar.gz ++++++ /work/SRC/openSUSE:Factory/semaphore/web-2.18.8.tar.gz /work/SRC/openSUSE:Factory/.semaphore.new.2375/web-2.18.9.tar.gz differ: char 13, line 1
