Close issue if action cancelled (#4)
* Close issue if kill signal received * Refactor: Exiting main loop can close application without explicit call to os.Exit(0) * Leave a comment on the closed issue if the close handler is triggered * Accidentally deleted the final logging command * Fix punctuation on the closing comment * Handle the comment loop and interruption handling via channels and a select statement * Update main.go
This commit is contained in:
parent
c4714a2254
commit
c24bf80784
1 changed files with 94 additions and 50 deletions
144
main.go
144
main.go
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -12,6 +13,90 @@ import (
|
|||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
func handleInterrupt(client *github.Client, ctx context.Context, apprv *approvalEnvironment) {
|
||||
newState := "closed"
|
||||
closeComment := "Workflow cancelled, closing issue."
|
||||
fmt.Println(closeComment)
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
Body: &closeComment,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("error commenting on issue: %v\n", err)
|
||||
return
|
||||
}
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func newCommentLoopChannel(ctx context.Context, apprv *approvalEnvironment, client *github.Client, approvers []string, minimumApprovals int) chan int {
|
||||
channel := make(chan int)
|
||||
go func() {
|
||||
for {
|
||||
comments, _, err := client.Issues.ListComments(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueListCommentsOptions{})
|
||||
if err != nil {
|
||||
fmt.Printf("error getting comments: %v\n", err)
|
||||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
|
||||
approved, err := approvalFromComments(comments, approvers, minimumApprovals)
|
||||
if err != nil {
|
||||
fmt.Printf("error getting approval from comments: %v\n", err)
|
||||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
fmt.Printf("Workflow status: %s\n", approved)
|
||||
switch approved {
|
||||
case approvalStatusApproved:
|
||||
newState := "closed"
|
||||
closeComment := "All approvers have approved, continuing workflow and closing this issue."
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
Body: &closeComment,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("error commenting on issue: %v\n", err)
|
||||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
channel <- 0
|
||||
fmt.Println("Workflow manual approval completed")
|
||||
close(channel)
|
||||
case approvalStatusDenied:
|
||||
newState := "closed"
|
||||
closeComment := "Request denied. Closing issue and failing workflow."
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
Body: &closeComment,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("error commenting on issue: %v\n", err)
|
||||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
|
||||
time.Sleep(pollingInterval)
|
||||
}
|
||||
}()
|
||||
return channel
|
||||
}
|
||||
|
||||
func newGithubClient(ctx context.Context) *github.Client {
|
||||
token := os.Getenv(envVarToken)
|
||||
ts := oauth2.StaticTokenSource(
|
||||
|
|
@ -64,57 +149,16 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
commentLoop:
|
||||
for {
|
||||
comments, _, err := client.Issues.ListComments(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueListCommentsOptions{})
|
||||
if err != nil {
|
||||
fmt.Printf("error getting comments: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
killSignalChannel := make(chan os.Signal, 1)
|
||||
signal.Notify(killSignalChannel, os.Interrupt)
|
||||
|
||||
approved, err := approvalFromComments(comments, approvers, minimumApprovals)
|
||||
if err != nil {
|
||||
fmt.Printf("error getting approval from comments: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Workflow status: %s\n", approved)
|
||||
switch approved {
|
||||
case approvalStatusApproved:
|
||||
newState := "closed"
|
||||
closeComment := "All approvers have approved, continuing workflow and closing this issue."
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
Body: &closeComment,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("error commenting on issue: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
break commentLoop
|
||||
case approvalStatusDenied:
|
||||
newState := "closed"
|
||||
closeComment := "Request denied. Closing issue and failing workflow."
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
Body: &closeComment,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("error commenting on issue: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
commentLoopChannel := newCommentLoopChannel(ctx, apprv, client, approvers, minimumApprovals)
|
||||
|
||||
time.Sleep(pollingInterval)
|
||||
select {
|
||||
case exitCode := <-commentLoopChannel:
|
||||
os.Exit(exitCode)
|
||||
case _ = <-killSignalChannel:
|
||||
handleInterrupt(client, ctx, apprv)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Workflow manual approval completed")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue