Adding the capability to create the approval issue in the another repository (#142)
* Adding the capability to create the approval issue in another repository * reverting testing changes * reverting test changes contd. * Updating readme and removing a debug line * Introduce a 'fail-on-denial' boolean (#147) * Introduce a 'fail-on-approval' boolean * Use test docker image * oops * change default and fix logic * Update action.yaml * Fix linting error * Adding the capability to create the approval issue in another repository * reverting testing changes * reverting test changes contd. * moving targetRepo inputs from env vars to action-args * Update constants.go * Update constants.go to resolve nuances created by inconsistent tab length settings --------- Co-authored-by: Liz MacLean <18120837+lizziemac@users.noreply.github.com>
This commit is contained in:
parent
aba06e32f1
commit
c17f1c63ff
6 changed files with 55 additions and 12 deletions
1
.github/workflows/ci.yaml
vendored
1
.github/workflows/ci.yaml
vendored
|
|
@ -20,6 +20,7 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build
|
||||
run: make build
|
||||
env:
|
||||
|
|
|
|||
19
README.md
19
README.md
|
|
@ -46,6 +46,25 @@ steps:
|
|||
- `additional-approved-words` is a comma separated list of strings to expand the dictionary of words that indicate approval. This is optional and defaults to an empty string.
|
||||
- `additional-denied-words` is a comma separated list of strings to expand the dictionary of words that indicate denial. This is optional and defaults to an empty string.
|
||||
|
||||
### Creating Issues in a different repository
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: trstringer/manual-approval@v1
|
||||
with:
|
||||
secret: ${{ github.TOKEN }}
|
||||
approvers: user1,user2,org-team1
|
||||
minimum-approvals: 1
|
||||
issue-title: "Deploying v1.3.5 to prod from staging"
|
||||
issue-body: "Please approve or deny the deployment of version v1.3.5."
|
||||
exclude-workflow-initiator-as-approver: false
|
||||
additional-approved-words: ''
|
||||
additional-denied-words: ''
|
||||
target-repository: repository-name
|
||||
target-repository-owner: owner-id
|
||||
```
|
||||
- if either of `target-repository` or `target-repository-owner` is missing or is an empty string then the issue will be created in the same repository where this step is used.
|
||||
|
||||
### Using Custom Words
|
||||
|
||||
GitHub has a rich library of emojis, and these all work in additional approved words or denied words. Some values GitHub will store in their text version - i.e. `:shipit:`. Other emojis, GitHub will store in their unicode emoji form, like ✅.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ inputs:
|
|||
description: Comma separated list of words that can be used to deny beyond the defaults.
|
||||
required: false
|
||||
default: ''
|
||||
target-repository-owner:
|
||||
description: Owner of the repository in which the issue will be created.
|
||||
default: ''
|
||||
target-repository:
|
||||
description: Name of the repository in which the issue will be created.
|
||||
default: ''
|
||||
fail-on-denial:
|
||||
description: Whether or not to fail the workflow if the approval is denied
|
||||
required: false
|
||||
|
|
|
|||
12
approval.go
12
approval.go
|
|
@ -21,10 +21,12 @@ type approvalEnvironment struct {
|
|||
issueBody string
|
||||
issueApprovers []string
|
||||
minimumApprovals int
|
||||
targetRepoOwner string
|
||||
targetRepoName string
|
||||
failOnDenial bool
|
||||
}
|
||||
|
||||
func newApprovalEnvironment(client *github.Client, repoFullName, repoOwner string, runID int, approvers []string, minimumApprovals int, issueTitle, issueBody string, failOnDenial bool) (*approvalEnvironment, error) {
|
||||
func newApprovalEnvironment(client *github.Client, repoFullName, repoOwner string, runID int, approvers []string, minimumApprovals int, issueTitle, issueBody string, targetRepoOwner string, targetRepoName string, failOnDenial bool) (*approvalEnvironment, error) {
|
||||
repoOwnerAndName := strings.Split(repoFullName, "/")
|
||||
if len(repoOwnerAndName) != 2 {
|
||||
return nil, fmt.Errorf("repo owner and name in unexpected format: %s", repoFullName)
|
||||
|
|
@ -41,6 +43,8 @@ func newApprovalEnvironment(client *github.Client, repoFullName, repoOwner strin
|
|||
minimumApprovals: minimumApprovals,
|
||||
issueTitle: issueTitle,
|
||||
issueBody: issueBody,
|
||||
targetRepoOwner: targetRepoOwner,
|
||||
targetRepoName: targetRepoName,
|
||||
failOnDenial: failOnDenial,
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -79,13 +83,13 @@ Respond %s to continue workflow or %s to cancel.`,
|
|||
var err error
|
||||
fmt.Printf(
|
||||
"Creating issue in repo %s/%s with the following content:\nTitle: %s\nApprovers: %s\nBody:\n%s\n",
|
||||
a.repoOwner,
|
||||
a.repo,
|
||||
a.targetRepoOwner,
|
||||
a.targetRepoName,
|
||||
issueTitle,
|
||||
a.issueApprovers,
|
||||
issueBody,
|
||||
)
|
||||
a.approvalIssue, _, err = a.client.Issues.Create(ctx, a.repoOwner, a.repo, &github.IssueRequest{
|
||||
a.approvalIssue, _, err = a.client.Issues.Create(ctx, a.targetRepoOwner, a.targetRepoName, &github.IssueRequest{
|
||||
Title: &issueTitle,
|
||||
Body: &issueBody,
|
||||
Assignees: &a.issueApprovers,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ const (
|
|||
envVarAdditionalApprovedWords string = "INPUT_ADDITIONAL-APPROVED-WORDS"
|
||||
envVarAdditionalDeniedWords string = "INPUT_ADDITIONAL-DENIED-WORDS"
|
||||
envVarFailOnDenial string = "INPUT_FAIL-ON-DENIAL"
|
||||
envVarTargetRepoOwner string = "INPUT_TARGET-REPOSITORY-OWNER"
|
||||
envVarTargetRepo string = "INPUT_TARGET-REPOSITORY"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
27
main.go
27
main.go
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v43/github"
|
||||
|
|
@ -29,14 +30,14 @@ func handleInterrupt(ctx context.Context, client *github.Client, apprv *approval
|
|||
newState := "closed"
|
||||
closeComment := "Workflow cancelled, closing issue."
|
||||
fmt.Println(closeComment)
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.targetRepoOwner, apprv.targetRepoName, 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})
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.targetRepoOwner, apprv.targetRepoName, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
return
|
||||
|
|
@ -47,7 +48,7 @@ func newCommentLoopChannel(ctx context.Context, apprv *approvalEnvironment, clie
|
|||
channel := make(chan int)
|
||||
go func() {
|
||||
for {
|
||||
comments, _, err := client.Issues.ListComments(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueListCommentsOptions{})
|
||||
comments, _, err := client.Issues.ListComments(ctx, apprv.targetRepoOwner, apprv.targetRepoName, apprv.approvalIssueNumber, &github.IssueListCommentsOptions{})
|
||||
if err != nil {
|
||||
fmt.Printf("error getting comments: %v\n", err)
|
||||
channel <- 1
|
||||
|
|
@ -65,7 +66,7 @@ func newCommentLoopChannel(ctx context.Context, apprv *approvalEnvironment, clie
|
|||
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{
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.targetRepoOwner, apprv.targetRepoName, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
Body: &closeComment,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -73,7 +74,7 @@ func newCommentLoopChannel(ctx context.Context, apprv *approvalEnvironment, clie
|
|||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.targetRepoOwner, apprv.targetRepoName, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
channel <- 1
|
||||
|
|
@ -92,7 +93,7 @@ func newCommentLoopChannel(ctx context.Context, apprv *approvalEnvironment, clie
|
|||
}
|
||||
closeComment += " workflow."
|
||||
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
_, _, err := client.Issues.CreateComment(ctx, apprv.targetRepoOwner, apprv.targetRepoName, apprv.approvalIssueNumber, &github.IssueComment{
|
||||
Body: &closeComment,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -100,7 +101,7 @@ func newCommentLoopChannel(ctx context.Context, apprv *approvalEnvironment, clie
|
|||
channel <- 1
|
||||
close(channel)
|
||||
}
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.repoOwner, apprv.repo, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
_, _, err = client.Issues.Edit(ctx, apprv.targetRepoOwner, apprv.targetRepoName, apprv.approvalIssueNumber, &github.IssueRequest{State: &newState})
|
||||
if err != nil {
|
||||
fmt.Printf("error closing issue: %v\n", err)
|
||||
channel <- 1
|
||||
|
|
@ -169,6 +170,9 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
targetRepoName := os.Getenv(envVarTargetRepo)
|
||||
targetRepoOwner := os.Getenv(envVarTargetRepoOwner)
|
||||
|
||||
repoFullName := os.Getenv(envVarRepoFullName)
|
||||
runID, err := strconv.Atoi(os.Getenv(envVarRunID))
|
||||
if err != nil {
|
||||
|
|
@ -177,6 +181,12 @@ func main() {
|
|||
}
|
||||
repoOwner := os.Getenv(envVarRepoOwner)
|
||||
|
||||
if targetRepoName == "" || targetRepoOwner == "" {
|
||||
parts := strings.SplitN(repoFullName, "/", 2)
|
||||
targetRepoOwner = parts[0]
|
||||
targetRepoName = parts[1]
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
client, err := newGithubClient(ctx)
|
||||
if err != nil {
|
||||
|
|
@ -211,7 +221,8 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
apprv, err := newApprovalEnvironment(client, repoFullName, repoOwner, runID, approvers, minimumApprovals, issueTitle, issueBody, failOnDenial)
|
||||
|
||||
apprv, err := newApprovalEnvironment(client, repoFullName, repoOwner, runID, approvers, minimumApprovals, issueTitle, issueBody, targetRepoOwner, targetRepoName, failOnDenial)
|
||||
if err != nil {
|
||||
fmt.Printf("error creating approval environment: %v\n", err)
|
||||
os.Exit(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue