Skip to content

Commit

Permalink
✨ Manage milestones
Browse files Browse the repository at this point in the history
Signed-off-by: David Zager <[email protected]>
  • Loading branch information
djzager committed Oct 16, 2023
1 parent bf178dd commit d06020d
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 32 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/manage-milestone.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Manage Milestone

on:
workflow_dispatch:
inputs:
title:
description: Title of the milestone
required: true
type: string
state:
description: The state (open|closed) of the milestone
required: false
default: "open"
type: string
description:
description: Description of the milestone
required: false
default: ""
type: string
due:
description: Due date (DateOnly format https://pkg.go.dev/time#pkg-constants)
required: false
default: ""
type: string

jobs:
sync-labels:
name: Synchronize Labels
runs-on: ubuntu-latest
strategy:
matrix:
repos:
- org: konveyor
repo: release-tools
fail-fast: true
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Manage Milestone
uses: ./cmd/milestones
with:
github_token: ${{ secrets.GH_TOKEN }}
organization: ${{ matrix.repos.org }}
repository: ${{ matrix.repos.repo }}
title: ${{ inputs.title }}
state: ${{ inputs.state }}
description: ${{ inputs.description }}
due: ${{ inputs.due }}
2 changes: 1 addition & 1 deletion cmd/labels/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ runs:
- name: See environment
run: env
shell: bash
- name: Run verify
- name: Run action
env:
GITHUB_TOKEN: ${{ inputs.github_token }}
run: |
Expand Down
32 changes: 1 addition & 31 deletions cmd/labels/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ import (
"flag"
"fmt"
"log"
"net/http"
"net/url"
"os"
"strings"

"github.com/google/go-github/v55/github"
"github.com/konveyor/release-tools/pkg/action"
"golang.org/x/oauth2"
"sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -88,33 +85,6 @@ func (label *Label) Print() {
fmt.Println("------------------------")
}

func GetClient() *github.Client {
baseURL, err := url.Parse("https://api.github.com")
if err != nil {
action.ErrorCommand("Bad endpoint")
os.Exit(1)
}
if !strings.HasSuffix(baseURL.Path, "/") {
baseURL.Path += "/"
}
token := os.Getenv("GITHUB_TOKEN")
if token == "" {
action.ErrorCommand("GITHUB_TOKEN environment variable not specified")
os.Exit(1)
}

httpClient := &http.Client{
Transport: &oauth2.Transport{
Base: http.DefaultTransport,
Source: oauth2.ReuseTokenSource(nil, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})),
},
}
client := github.NewClient(httpClient)
client.BaseURL = baseURL

return client
}

func main() {
orgPtr := flag.String("org", "", "The organization for the repo")
repoPtr := flag.String("repo", "", "The repository")
Expand Down Expand Up @@ -151,7 +121,7 @@ func main() {
fmt.Println()

// Instantiate the client and get the current labels on the repo
client := GetClient()
client := action.GetClient()
opt := &github.ListOptions{
PerPage: 100,
}
Expand Down
53 changes: 53 additions & 0 deletions cmd/milestones/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Manage Milestone
description: Manage a Milestone in a Repository
inputs:
github_token:
description: "the github_token provided by the actions runner"
required: true
type: string
organization:
description: "The organization"
required: true
type: string
repository:
description: "The repository"
required: true
type: string
title:
description: Title of the milestone
required: true
type: string
state:
description: The state (open|closed) of the milestone
required: true
type: string
description:
description: Description of the milestone
required: true
type: string
due:
description: Due date (DateOnly format https://pkg.go.dev/time#pkg-constants)
required: true
type: string
runs:
using: composite
steps:
- name: Set up Go
uses: actions/setup-go@v3
- name: See environment
run: env
shell: bash
- name: Run action
env:
GITHUB_TOKEN: ${{ inputs.github_token }}
ORGANIZATION: ${{ inputs.organization }}
REPOSITORY: ${{ inputs.repository }}
TITLE: ${{ inputs.title }}
STATE: ${{ inputs.state }}
DESCRIPTION: ${{ inputs.description }}
DUE: ${{ inputs.due }}
run: |
cd ${GITHUB_ACTION_PATH}
go mod download
go run main.go
shell: bash
103 changes: 103 additions & 0 deletions cmd/milestones/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package main

import (
"context"
"fmt"
"log"
"os"
"time"

"github.com/google/go-github/v55/github"
"github.com/konveyor/release-tools/pkg/action"
)

func main() {
org := os.Getenv("ORGANIZATION")
repo := os.Getenv("REPOSITORY")
title := os.Getenv("TITLE")
state := os.Getenv("STATE")
desc := os.Getenv("DESCRIPTION")
due := os.Getenv("DUE")

if org == "" {
action.ErrorCommand("input 'organization' not defined")
os.Exit(1)
}
if repo == "" {
action.ErrorCommand("input 'repository' not defined")
os.Exit(1)
}
if title == "" {
action.ErrorCommand("input 'title' not defined")
os.Exit(1)
}
if state != "open" && state != "closed" {
action.ErrorCommand("input 'state' must be 'open' or 'closed'")
os.Exit(1)
}

var dueTime *github.Timestamp
if due != "" {
parsedTime, err := time.Parse(time.DateOnly, due)
if err != nil {
fmt.Println("Error: " + err.Error())
action.ErrorCommand("input 'due' not parseable as DateOnly time")
os.Exit(1)
}
dueOn := github.Timestamp{Time: parsedTime}
dueTime = &dueOn
}

desiredMilestone := github.Milestone{
Title: &title,
State: &state,
Description: &desc,
DueOn: dueTime,
}

// Instantiate the client and get milestones
client := action.GetClient()
opt := &github.MilestoneListOptions{
ListOptions: github.ListOptions{
PerPage: 100,
},
}

// Make sure we get all the milestones
var currentMilestones []*github.Milestone
for {
labels, resp, err := client.Issues.ListMilestones(context.Background(), org, repo, opt)
if err != nil {
action.ErrorCommand("Failed to get repo labels")
log.Fatal(err)
}
currentMilestones = append(currentMilestones, labels...)
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}

// Grab the milestone number if it already exists
for _, milestone := range currentMilestones {
if *milestone.Title == *desiredMilestone.Title {
desiredMilestone.Number = milestone.Number
}
}

if desiredMilestone.Number == nil {
_, _, err := client.Issues.CreateMilestone(context.Background(), org, repo, &desiredMilestone)
if err != nil {
action.ErrorCommand("Error creating milestone")
log.Fatal(err)
}
return
}
_, _, err := client.Issues.EditMilestone(context.Background(), org, repo, *desiredMilestone.Number, &desiredMilestone)
if err != nil {
action.ErrorCommand("Error editingmilestone")
log.Fatal(err)
}

action.NoticeCommand("Yay")
}
38 changes: 38 additions & 0 deletions pkg/action/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package action

import (
"net/http"
"net/url"
"os"
"strings"

"github.com/google/go-github/v55/github"
"golang.org/x/oauth2"
)

func GetClient() *github.Client {
baseURL, err := url.Parse("https://api.github.com")
if err != nil {
ErrorCommand("Bad endpoint")
os.Exit(1)
}
if !strings.HasSuffix(baseURL.Path, "/") {
baseURL.Path += "/"
}
token := os.Getenv("GITHUB_TOKEN")
if token == "" {
ErrorCommand("GITHUB_TOKEN environment variable not specified")
os.Exit(1)
}

httpClient := &http.Client{
Transport: &oauth2.Transport{
Base: http.DefaultTransport,
Source: oauth2.ReuseTokenSource(nil, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})),
},
}
client := github.NewClient(httpClient)
client.BaseURL = baseURL

return client
}

0 comments on commit d06020d

Please sign in to comment.