Skip to content

Commit

Permalink
add go utility on generating git issues at provider repos
Browse files Browse the repository at this point in the history
  • Loading branch information
nawazkh committed Aug 8, 2023
1 parent 59b8c79 commit aa09895
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,15 @@ $(GINKGO): # Build ginkgo from tools folder.
$(GOLANGCI_LINT): # Build golangci-lint from tools folder.
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOLANGCI_LINT_PKG) $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER)

.PHONY: provider-issues
provider-issues: # Creates issues for all CAPI providers
@if [ -n "${GITHUB_ISSUE_OPENER_TOKEN}" ]; then \
go run ./hack/tools/update_providers/open_issues.go --dryRun="false" --token=${GITHUB_ISSUE_OPENER_TOKEN}; \
else \
echo "Github token GITHUB_ISSUE_OPENER_TOKEN" not set; \
fi


## --------------------------------------
## Helpers
## --------------------------------------
Expand Down
28 changes: 28 additions & 0 deletions hack/tools/update_providers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# open_issues

`open_issues` is a go utility intended to open git issues on provider repos.

## Pre-requisites

- Create a github token which has a access to the following scopes. And save it in your environment as `GITHUB_ISSUE_OPENER_TOKEN`
- `repo:status` - Grants access to commit status on public and private repositories.
- `repo_deployment` - Grants access to deployment statuses on public and private repositories.
- `public_repo` - Grants access to public repositories
- Decide upon the title of the issue to be opened. Update it in the utility.
- Update the issue body

## How to run the tool

- From the root of the project Cluster API, run below to dry run the utility.

```go
make provider-issues-dry-run
```

OR

run below to create the issues at the provider repositories.

```sh
make provider-issues
```
189 changes: 189 additions & 0 deletions hack/tools/update_providers/open_issues.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
//go:build tools
// +build tools

/*
Copyright 2023 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// main is the main package for the open issues utility.
package main

import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io"
"net/http"
"os"
"strings"
)

const (
baseURL = "https://api.github.com"
issueTitle = "CAPI v1.x.0-beta.0 has been released and is ready for testing"
)

var (
repoList = []string{
"kubernetes-sigs/cluster-api-addon-provider-helm",
"kubernetes-sigs/cluster-api-provider-aws",
"kubernetes-sigs/cluster-api-provider-azure",
"kubernetes-sigs/cluster-api-provider-cloudstack",
"kubernetes-sigs/cluster-api-provider-digitalocean",
"kubernetes-sigs/cluster-api-provider-gcp",
"kubernetes-sigs/cluster-api-provider-kubemark",
"kubernetes-sigs/cluster-api-provider-kubevirt",
"kubernetes-sigs/cluster-api-provider-ibmcloud",
"kubernetes-sigs/cluster-api-provider-nested",
"oracle/cluster-api-provider-oci",
"kubernetes-sigs/cluster-api-provider-openstack",
"kubernetes-sigs/cluster-api-operator",
"kubernetes-sigs/cluster-api-provider-packet",
"kubernetes-sigs/cluster-api-provider-vsphere",
}
)

type Issue struct {

Check warning on line 59 in hack/tools/update_providers/open_issues.go

View workflow job for this annotation

GitHub Actions / lint (hack/tools)

exported: exported type Issue should have comment or be unexported (revive)
Title string `json:"title"`
Body string `json:"body"`
}

type IssueResponse struct {

Check warning on line 64 in hack/tools/update_providers/open_issues.go

View workflow job for this annotation

GitHub Actions / lint (hack/tools)

exported: exported type IssueResponse should have comment or be unexported (revive)
HTMLURL string `json:"html_url"`
}

func main() {
token := flag.String("token", "", "GitHub personal access token")
dryRun := flag.String("dryRun", "true", "Dry run")
flag.Parse()

if *token == "" {
fmt.Println("GitHub personal access token is required.")
os.Exit(1)
}

issueBody := `
<!-- body -->
<!-- TODO: remove all TODOs before running this utility -->
<!-- TODO: update CAPI release semver -->
CAPI v1.x.0-beta.0 has been released and is ready for testing.
Looking forward to your feedback before CAPI 1.x.0 release!
## For quick reference
<!-- body -->
<!-- TODO: CAPI release notes -->
- [CAPI v1.x.0-beta.0 release notes](https://github.com/kubernetes-sigs/cluster-api/releases/tag/v1.x.0-beta.0)
- [Shortcut to CAPI git issues](https://github.com/kubernetes-sigs/cluster-api/issues)
## Following are the planned dates for the upcoming releases
<!-- TODO: update CAPI release timeline -->
|Release|Expected Date|
|-----|-----|
|v1.5.0-beta.x | Tuesday 5th July 2023|
|release-1.5 branch created (Begin [Code Freeze])|Tuesday 11th July 2023|
|v1.5.0-rc.0 released|Tuesday 11th July 2023|
| release-1.5 jobs created | Tuesday 11th July 2023 |
| v1.5.0-rc.x released | Tuesday 18th July 2023 |
| v1.5.0 released | Tuesday 25th July 2023 |
<!-- body -->
<!-- [List of CAPI providers](https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/release/release-tasks.md#communicate-beta-to-providers) -->
`

if *dryRun == "true" {
fmt.Printf("\n")
fmt.Println("###############################################")
fmt.Println("Dry run is enabled. No git issues will be created.")
fmt.Println("###############################################")
fmt.Printf("\n")
}

fmt.Println("\n\nCreating issues for the following repositories:")
fmt.Println(strings.Join(repoList, "\n"))
fmt.Printf("\n")

if *dryRun != "true" {
fmt.Println("Continue to create issues? (y/n)")
var response string
fmt.Scanln(&response)
if response != "y" {
fmt.Println("Aborting...")
os.Exit(0)
}
}
fmt.Printf("\n")

for _, repo := range repoList {
url := fmt.Sprintf("%s/repos/%s/issues", baseURL, repo)
if *dryRun == "true" {
fmt.Printf("Dry run: %s\n", url)
continue
}

issue := Issue{
Title: issueTitle,
Body: issueBody,
}

issueJSON, err := json.Marshal(issue)
if err != nil {
fmt.Printf("Failed to marshal issue: %s\n", err)
os.Exit(1)
}

req, err := http.NewRequest("POST", url, bytes.NewBuffer(issueJSON))
// fmt.Println("Request will be sent at:", req.URL)
if err != nil {
fmt.Printf("Failed to create request: %s\n", err)
os.Exit(1)
}

req.Header.Set("Accept", "application/vnd.github+json")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", *token))
req.Header.Set("X-Github-Api-Version", "2022-11-28")
req.Header.Set("User-Agent", "open_git_issues")
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("Failed to send request: %s\n", err)
os.Exit(1)
}

defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
fmt.Printf("Failed to create issue for repository '%s'\nStatus code: %d\nStatus:%s\n\n\n", repo, resp.StatusCode, resp.Status)
} else {
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Printf("Failed to read response body: %s\n", err)
os.Exit(1)
}

var issueResponse IssueResponse
err = json.Unmarshal(responseBody, &issueResponse)
if err != nil {
fmt.Printf("Failed to unmarshal issue response: %s\n", err)
os.Exit(1)
}

fmt.Printf("\nIssue created for repository '%s'\nURL: %s\n", repo, issueResponse.HTMLURL)
}
}
}

0 comments on commit aa09895

Please sign in to comment.