Skip to content

Commit

Permalink
add genereate metrics cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
tashima42 committed Dec 13, 2024
1 parent f0ed6cd commit d4dbf50
Show file tree
Hide file tree
Showing 2 changed files with 228 additions and 19 deletions.
109 changes: 90 additions & 19 deletions cmd/release/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/google/go-github/v39/github"
"github.com/rancher/ecm-distro-tools/release"
"github.com/rancher/ecm-distro-tools/release/k3s"
"github.com/rancher/ecm-distro-tools/release/metrics"
"github.com/rancher/ecm-distro-tools/release/rancher"
"github.com/rancher/ecm-distro-tools/repository"
"github.com/spf13/cobra"
Expand All @@ -25,25 +27,28 @@ var (
dashboardPrevMilestone string
dashboardMilestone string

concurrencyLimit int
imagesListURL string
ignoreImages []string
checkImages []string
registry string
username string
password string
rancherMissingImagesJSONOutput bool
rke2PrevMilestone string
rke2Milestone string
rancherArtifactsIndexWriteToPath string
rancherArtifactsIndexIgnoreVersions []string
rancherImagesDigestsOutputFile string
rancherImagesDigestsRegistry string
rancherImagesDigestsImagesURL string
rancherSyncImages []string
rancherSourceRegistry string
rancherTargetRegistry string
rancherSyncConfigOutputPath string
concurrencyLimit int
imagesListURL string
ignoreImages []string
checkImages []string
registry string
username string
password string
rancherMissingImagesJSONOutput bool
rke2PrevMilestone string
rke2Milestone string
rancherArtifactsIndexWriteToPath string
rancherArtifactsIndexIgnoreVersions []string
rancherImagesDigestsOutputFile string
rancherImagesDigestsRegistry string
rancherImagesDigestsImagesURL string
rancherSyncImages []string
rancherSourceRegistry string
rancherTargetRegistry string
rancherSyncConfigOutputPath string
rancherMetricsRancherReleasesFilePath string
rancherMetricsWorkflowsFilePath string
rancherMetricsPrimeReleasesFilePath string
)

// generateCmd represents the generate command
Expand Down Expand Up @@ -177,6 +182,54 @@ var rancherGenerateImagesSyncConfigSubCmd = &cobra.Command{
},
}

var rancherGenerateMetricsSubCmd = &cobra.Command{
Use: "metrics",
Short: "Generate rancher release metrics",
RunE: func(cmd *cobra.Command, args []string) error {
var rancherReleases []github.RepositoryRelease
var primeReleases []github.RepositoryRelease
var workflows []github.WorkflowRun

rancherReleasesFile, err := os.ReadFile(rancherMetricsRancherReleasesFilePath)
if err != nil {
return err
}
if err := json.Unmarshal(rancherReleasesFile, &rancherReleases); err != nil {
return err
}

primeReleasesFile, err := os.ReadFile(rancherMetricsPrimeReleasesFilePath)
if err != nil {
return err
}
if err := json.Unmarshal(primeReleasesFile, &primeReleases); err != nil {
return err
}

workflowsFile, err := os.ReadFile(rancherMetricsWorkflowsFilePath)
if err != nil {
return err
}
if err := json.Unmarshal(workflowsFile, &workflows); err != nil {
return err
}

metrics, err := metrics.ExtractMetrics(rancherReleases, primeReleases, workflows)
if err != nil {
return err
}

b, err := json.MarshalIndent(metrics, "", " ")
if err != nil {
return err
}

fmt.Println(string(b))

return nil
},
}

var uiGenerateSubCmd = &cobra.Command{
Use: "ui",
Short: "Generate ui related artifacts",
Expand Down Expand Up @@ -233,6 +286,7 @@ func init() {
rancherGenerateSubCmd.AddCommand(rancherGenerateMissingImagesListSubCmd)
rancherGenerateSubCmd.AddCommand(rancherGenerateDockerImagesDigestsSubCmd)
rancherGenerateSubCmd.AddCommand(rancherGenerateImagesSyncConfigSubCmd)
rancherGenerateSubCmd.AddCommand(rancherGenerateMetricsSubCmd)
uiGenerateSubCmd.AddCommand(uiGenerateReleaseNotesSubCmd)
dashboardGenerateSubCmd.AddCommand(dashboardGenerateReleaseNotesSubCmd)

Expand Down Expand Up @@ -343,4 +397,21 @@ func init() {
fmt.Println(err.Error())
os.Exit(1)
}

// rancher generate metrics
rancherGenerateMetricsSubCmd.Flags().StringVarP(&rancherMetricsRancherReleasesFilePath, "rancher-releases-file", "r", "", "Path to the releases file")
rancherGenerateMetricsSubCmd.Flags().StringVarP(&rancherMetricsWorkflowsFilePath, "workflows-file", "w", "", "Path to the workflows file")
rancherGenerateMetricsSubCmd.Flags().StringVarP(&rancherMetricsPrimeReleasesFilePath, "prime-releases-file", "p", "", "Path to the prime releases file")
if err := rancherGenerateMetricsSubCmd.MarkFlagRequired("rancher-releases-file"); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if err := rancherGenerateMetricsSubCmd.MarkFlagRequired("workflows-file"); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if err := rancherGenerateMetricsSubCmd.MarkFlagRequired("prime-releases-file"); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
}
138 changes: 138 additions & 0 deletions release/metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package metrics

import (
"strings"

"github.com/google/go-github/v39/github"
)

type (
yearMonthMap map[int]*[12]int
yearMap map[int]int
)

type Metrics struct {
Rancher ReleaseMetrics `json:"rancher"`
RancherPrime ReleaseMetrics `json:"rancher_prime"`
Workflows WorkflowsMetrics `json:"actions"`
}

type ReleaseMetrics struct {
// Number of GA releases per year and month
// Value: Number of releases per month (Jan: 0, Feb: 1, ..., Dec: 11)
GAReleasesPerMonth yearMonthMap `json:"ga_releases_per_month"`
// Number of Pre-releases per year and month (any release with a suffix that starts with a dash '-*')
// Value: Number of releases per month (Jan: 0, Feb: 1, ..., Dec: 11)
PreReleasesPerMonth yearMonthMap `json:"pre_releases_per_month"`
// Number of GA releases per year
// Value: Number of releases per year
GAReleasesPerYear yearMap `json:"ga_releases_per_year"`
// Number of Pre-releases per year
// Value: Number of releases per year
PreReleasesPerYear yearMap `json:"pre_releases_per_year"`
}

type WorkflowsMetrics struct {
// Number of successful actions per year and month
// Key: Year
// Value: Number of successful actions per month (Jan: 0, Feb: 1, ..., Dec: 11)
SuccessfulWorkflowsPerMonth yearMonthMap `json:"successful_actions_per_month"`
// Number of failed actions per year and month
// Key: Year
// Value: Number of failed actions per month (Jan: 0, Feb: 1, ..., Dec: 11)
FailedWorkflowsPerMonth yearMonthMap `json:"failed_actions_per_month"`
}

func ExtractMetrics(rancherReleases []github.RepositoryRelease, primeReleases []github.RepositoryRelease, workflows []github.WorkflowRun) (Metrics, error) {
var metrics Metrics

rancher, err := extractReleaseMetrics(rancherReleases)
if err != nil {
return metrics, err
}

rancherPrimeReleases, err := extractReleaseMetrics(primeReleases)

workflowsMetrics, err := extractWorkflowsMetrics(workflows)
if err != nil {
return metrics, err
}

metrics.Rancher = rancher
metrics.RancherPrime = rancherPrimeReleases
metrics.Workflows = workflowsMetrics

return metrics, nil
}

func extractReleaseMetrics(releases []github.RepositoryRelease) (ReleaseMetrics, error) {
var metrics ReleaseMetrics

metrics.GAReleasesPerMonth = make(yearMonthMap)
metrics.PreReleasesPerMonth = make(yearMonthMap)
metrics.GAReleasesPerYear = make(yearMap)
metrics.PreReleasesPerYear = make(yearMap)

for _, release := range releases {
releaseDate := release.GetCreatedAt().Time

monthIndex := int(releaseDate.Month() - 1)
year := releaseDate.Year()

if _, ok := metrics.GAReleasesPerMonth[year]; !ok {
metrics.GAReleasesPerMonth[year] = &[12]int{}
}
if _, ok := metrics.PreReleasesPerMonth[year]; !ok {
metrics.PreReleasesPerMonth[year] = &[12]int{}
}

// is pre-release
if strings.Contains(release.GetTagName(), "-") {
metrics.PreReleasesPerMonth[year][monthIndex]++
} else {
metrics.GAReleasesPerMonth[year][monthIndex]++
}
}

for year, releases := range metrics.GAReleasesPerMonth {
for _, count := range releases {
metrics.GAReleasesPerYear[year] += count
}
}

for year, releases := range metrics.PreReleasesPerMonth {
for _, count := range releases {
metrics.PreReleasesPerYear[year] += count
}
}

return metrics, nil
}

func extractWorkflowsMetrics(workflows []github.WorkflowRun) (WorkflowsMetrics, error) {
var metrics WorkflowsMetrics

metrics.SuccessfulWorkflowsPerMonth = make(yearMonthMap)
metrics.FailedWorkflowsPerMonth = make(yearMonthMap)

for _, workflow := range workflows {
workflowDate := workflow.GetCreatedAt().Time

monthIndex := int(workflowDate.Month() - 1)
year := workflowDate.Year()

if _, ok := metrics.SuccessfulWorkflowsPerMonth[year]; !ok {
metrics.SuccessfulWorkflowsPerMonth[year] = &[12]int{}
}
if _, ok := metrics.FailedWorkflowsPerMonth[year]; !ok {
metrics.FailedWorkflowsPerMonth[year] = &[12]int{}
}

if workflow.GetConclusion() == "success" {
metrics.SuccessfulWorkflowsPerMonth[year][monthIndex]++
} else {
metrics.FailedWorkflowsPerMonth[year][monthIndex]++
}
}
return metrics, nil
}

0 comments on commit d4dbf50

Please sign in to comment.