summaryrefslogtreecommitdiff
path: root/generator
diff options
context:
space:
mode:
authorKubernetes Prow Robot <k8s-ci-robot@users.noreply.github.com>2023-01-15 23:38:50 -0800
committerGitHub <noreply@github.com>2023-01-15 23:38:50 -0800
commit06df99149cecf84431dca5259a56757393ea8268 (patch)
tree4cfdbdfa01ea2ed56f1e13bea50b84ae78900559 /generator
parent5b887a65cf81061146d9532f1938e8239184d397 (diff)
parent27ddce709366b6cc08c88f5e657d7cced0b0a8f5 (diff)
Merge pull request #7038 from Priyankasaggu11929/add-kep-automation-in-sig-template
auto generate list of KEPs in annual-report/sig_report go template
Diffstat (limited to 'generator')
-rw-r--r--generator/annual-report/sig_report.tmpl27
-rw-r--r--generator/app.go119
2 files changed, 124 insertions, 22 deletions
diff --git a/generator/annual-report/sig_report.tmpl b/generator/annual-report/sig_report.tmpl
index d018622a..475ab145 100644
--- a/generator/annual-report/sig_report.tmpl
+++ b/generator/annual-report/sig_report.tmpl
@@ -14,25 +14,16 @@
-
-
-3. KEP work in {{lastYear}} (1.x, 1.y, 1.z):
+{{$releases := getReleases}}
+3. KEP work in {{lastYear}} (v{{$releases.Latest}}, v{{$releases.LatestMinusOne}}, v{{$releases.LatestMinusTwo}}):
+{{$owingsig := .Dir}}
+{{- range $stage, $keps := filterKEPs $owingsig $releases}}
+ {{ $stage }}:
+ {{- range $keps}}
+ - [{{.Number}} - {{.Title}}](https://github.com/kubernetes/enhancements/tree/master/keps/{{.OwningSIG}}/{{.Name}}) - {{.LatestMilestone -}}
+ {{ end}}
+{{- end}}
-<!--
-In future, this will be generated from kubernetes/enhancements kep.yaml files
-1. with SIG as owning-sig or in participating-sigs
-2. listing 1.x, 1.y, or 1.z in milestones or in latest-milestone
--->
-
- - Stable
- - [$kep-number - $title](https://git.k8s.io/community/$link/README.md) - $milestone.stable
- - [$kep-number - $title](https://git.k8s.io/community/$link/README.md) - $milestone.stable
- - Beta
- - [$kep-number - $title](https://git.k8s.io/community/$link/README.md) - $milestone.beta
- - [$kep-number - $title](https://git.k8s.io/community/$link/README.md) - $milestone.beta
- - Alpha
- - [$kep-number - $title](https://git.k8s.io/community/$link/README.md) - $milestone.alpha
- - [$kep-number - $title](https://git.k8s.io/community/$link/README.md) - $milestone.alpha
- - Pre-alpha
- - [$kep-number - $title](https://git.k8s.io/community/$link/README.md)
## Project health
diff --git a/generator/app.go b/generator/app.go
index 0e67ec1d..6d631343 100644
--- a/generator/app.go
+++ b/generator/app.go
@@ -17,9 +17,12 @@ limitations under the License.
package main
import (
+ "context"
+ "encoding/json"
"fmt"
"io/ioutil"
"log"
+ "net/http"
"net/url"
"os"
"path/filepath"
@@ -29,6 +32,10 @@ import (
"text/template"
"time"
+ "k8s.io/enhancements/api"
+
+ "github.com/google/go-github/v32/github"
+
yaml "gopkg.in/yaml.v3"
)
@@ -55,13 +62,101 @@ const (
regexRawGitHubURL = "https://raw.githubusercontent.com/(?P<org>[^/]+)/(?P<repo>[^/]+)/(?P<branch>[^/]+)/(?P<path>.*)"
regexGitHubURL = "https://github.com/(?P<org>[^/]+)/(?P<repo>[^/]+)/(blob|tree)/(?P<branch>[^/]+)/(?P<path>.*)"
+
+ // For KEPs automation
+ kepURL = "https://storage.googleapis.com/k8s-keps/keps.json"
)
var (
baseGeneratorDir = ""
templateDir = "generator"
+ releases = Releases{}
+ cachedKEPs = []api.Proposal{}
)
+// KEP represents an individual KEP holding its metadata information.
+type KEP struct {
+ Name string `json:"name"`
+ Title string `json:"title"`
+ KepNumber string `json:"kepNumber"`
+ OwningSig string `json:"owningSig"`
+ Stage string `json:"stage"`
+ LatestMilestone string `json:"latestMilestone"`
+}
+
+type Releases struct {
+ Latest string
+ LatestMinusOne string
+ LatestMinusTwo string
+}
+
+// TODO: improve as suggested in https://github.com/kubernetes/community/pull/7038#discussion_r1069456087
+func getLastThreeK8sReleases() (Releases, error) {
+ ctx := context.Background()
+ client := github.NewClient(nil)
+
+ releases, _, err := client.Repositories.ListReleases(ctx, "kubernetes", "kubernetes", nil)
+ if err != nil {
+ return Releases{}, err
+ }
+ var result Releases
+ result.Latest = strings.Split(strings.TrimPrefix(*releases[0].TagName, "v"), ".")[0] + "." + strings.Split(strings.TrimPrefix(*releases[0].TagName, "v"), ".")[1]
+ result.LatestMinusOne = strings.Split(strings.TrimPrefix(*releases[1].TagName, "v"), ".")[0] + "." + strings.Split(strings.TrimPrefix(*releases[1].TagName, "v"), ".")[1]
+ result.LatestMinusTwo = strings.Split(strings.TrimPrefix(*releases[2].TagName, "v"), ".")[0] + "." + strings.Split(strings.TrimPrefix(*releases[2].TagName, "v"), ".")[1]
+ return result, nil
+}
+
+func getReleases() Releases {
+ return releases
+}
+
+func fetchKEPs() error {
+ url, err := url.Parse(kepURL)
+ if err != nil {
+ return fmt.Errorf("Error parsing url: %v", err)
+ }
+
+ req, err := http.NewRequest("GET", url.String(), nil)
+ if err != nil {
+ return fmt.Errorf("Error creating request: %v", err)
+ }
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ return fmt.Errorf("Error fetching KEPs: %v", err)
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return fmt.Errorf("Error reading KEPs body: %v", err)
+ }
+
+ err = json.Unmarshal(body, &cachedKEPs)
+ if err != nil {
+ return fmt.Errorf("Error unmarshalling KEPs: %v", err)
+ }
+ return nil
+}
+
+func filterKEPs(owningSig string, releases Releases) (map[api.Stage][]api.Proposal, error) {
+ kepsByStage := make(map[api.Stage][]api.Proposal)
+ for _, kep := range cachedKEPs {
+ if kep.OwningSIG == owningSig {
+ for _, stage := range api.ValidStages {
+ if kep.Stage == stage && (strings.HasSuffix(kep.LatestMilestone, releases.Latest) ||
+ strings.HasSuffix(kep.LatestMilestone, releases.LatestMinusOne) ||
+ strings.HasSuffix(kep.LatestMilestone, releases.LatestMinusTwo)) {
+ kepsByStage[stage] = append(kepsByStage[stage], kep)
+ }
+ }
+ }
+ }
+
+ return kepsByStage, nil
+}
+
// FoldedString is a string that will be serialized in FoldedStyle by go-yaml
type FoldedString string
@@ -169,7 +264,8 @@ type Group struct {
Leadership LeadershipGroup `yaml:"leadership"`
Meetings []Meeting
Contact Contact
- Subprojects []Subproject `yaml:",omitempty"`
+ Subprojects []Subproject `yaml:",omitempty"`
+ KEPs map[string][]api.Proposal `yaml:",omitempty"`
}
type WGName string
@@ -436,6 +532,8 @@ var funcMap = template.FuncMap{
"now": time.Now,
"lastYear": lastYear,
"toUpper": strings.ToUpper,
+ "filterKEPs": filterKEPs,
+ "getReleases": getReleases,
}
// lastYear returns the last year as a string
@@ -456,8 +554,9 @@ func githubURL(url string) string {
}
// orgRepoPath converts either
-// - a regular GitHub url of form https://github.com/org/repo/blob/branch/path/to/file
-// - a raw GitHub url of form https://raw.githubusercontent.com/org/repo/branch/path/to/file
+// - a regular GitHub url of form https://github.com/org/repo/blob/branch/path/to/file
+// - a raw GitHub url of form https://raw.githubusercontent.com/org/repo/branch/path/to/file
+//
// to a string of form 'org/repo/path/to/file'
func orgRepoPath(url string) string {
for _, regex := range []string{regexRawGitHubURL, regexGitHubURL} {
@@ -686,10 +785,22 @@ func writeYaml(data interface{}, path string) error {
}
func main() {
+
+ // Fetch KEPs and cache them in the keps variable
+ err := fetchKEPs()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ releases, err = getLastThreeK8sReleases()
+ if err != nil {
+ log.Fatal(err)
+ }
+
yamlPath := filepath.Join(baseGeneratorDir, sigsYamlFile)
var ctx Context
- err := readYaml(yamlPath, &ctx)
+ err = readYaml(yamlPath, &ctx)
if err != nil {
log.Fatal(err)
}