Files
scaleset/examples/dockerscaleset/config.go
T
Francesco Renzi e4a017ce06 Initial commit for open source release 🚀
Co-authored-by: Francesco Renzi <rentziass@github.com>
Co-authored-by: Nikola Jokic <jokicnikola07@gmail.com>
2026-02-03 16:41:15 +01:00

142 lines
3.5 KiB
Go

package main
import (
"fmt"
"log/slog"
"net/url"
"os"
"strings"
"github.com/actions/scaleset"
)
type Config struct {
RegistrationURL string
MaxRunners int
MinRunners int
ScaleSetName string
Labels []string
RunnerGroup string
GitHubApp scaleset.GitHubAppAuth
Token string
RunnerImage string
LogLevel string
LogFormat string
}
func (c *Config) defaults() {
if c.RunnerGroup == "" {
c.RunnerGroup = scaleset.DefaultRunnerGroup
}
if c.RunnerImage == "" {
c.RunnerImage = "ghcr.io/actions/actions-runner:latest"
}
}
func (c *Config) Validate() error {
c.defaults()
if _, err := url.ParseRequestURI(c.RegistrationURL); err != nil {
return fmt.Errorf("invalid registration URL: %w, it should be the full URL of where you want to register your scale set, e.g. 'https://github.com/org/repo'", err)
}
appError := c.GitHubApp.Validate()
if c.Token == "" && appError != nil {
return fmt.Errorf("no credentials provided: either GitHub App (client id, installation id and private key) (recommended) or a Personal Access Token are required")
}
if c.ScaleSetName == "" {
return fmt.Errorf("scale set name is required")
}
for i, label := range c.Labels {
if strings.TrimSpace(label) == "" {
return fmt.Errorf("label at index %d is empty", i)
}
}
if c.MaxRunners < c.MinRunners {
return fmt.Errorf("max runners cannot be less than min-runners")
}
if c.RunnerGroup == "" {
return fmt.Errorf("runner group is required")
}
if c.RunnerImage == "" {
return fmt.Errorf("runner image is required")
}
return nil
}
// systemInfo serves as a base system info
func systemInfo(scaleSetID int) scaleset.SystemInfo {
return scaleset.SystemInfo{
System: "dockerscaleset",
Subsystem: "dockerscaleset",
CommitSHA: "NA", // You can leverage build flags to set commit SHA
Version: "0.1.0", // You can leverage build flags to set version
ScaleSetID: scaleSetID,
}
}
func (c *Config) ScalesetClient() (*scaleset.Client, error) {
if err := c.GitHubApp.Validate(); err == nil {
return scaleset.NewClientWithGitHubApp(
scaleset.ClientWithGitHubAppConfig{
GitHubConfigURL: c.RegistrationURL,
GitHubAppAuth: c.GitHubApp,
SystemInfo: systemInfo(0),
},
)
}
return scaleset.NewClientWithPersonalAccessToken(
scaleset.NewClientWithPersonalAccessTokenConfig{
GitHubConfigURL: c.RegistrationURL,
PersonalAccessToken: c.Token,
SystemInfo: systemInfo(0),
},
)
}
func (c *Config) Logger() *slog.Logger {
var lvl slog.Level
switch strings.ToLower(c.LogLevel) {
case "debug":
lvl = slog.LevelDebug
case "info":
lvl = slog.LevelInfo
case "warn":
lvl = slog.LevelWarn
case "error":
lvl = slog.LevelError
default:
lvl = slog.LevelInfo
}
switch c.LogFormat {
case "json":
return slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: lvl,
}))
case "text":
return slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: lvl,
}))
default:
return slog.New(slog.DiscardHandler)
}
}
// BuildLabels returns the labels to use for the runner scale set.
// If custom labels are provided, those are used; otherwise, the scale set name is used as the label.
func (c *Config) BuildLabels() []scaleset.Label {
if len(c.Labels) > 0 {
labels := make([]scaleset.Label, len(c.Labels))
for i, name := range c.Labels {
labels[i] = scaleset.Label{Name: strings.TrimSpace(name)}
}
return labels
}
return []scaleset.Label{{Name: c.ScaleSetName}}
}