Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the capability to create the approval issue in the another repository #142

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Build
run: make build
env:
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ 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: ''
env:
target-repository: repository-name
target-repository-owner: owner-id
```
- if any 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 and these two environment variables will be rendered moot.

### 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 ✅.
Expand Down
12 changes: 8 additions & 4 deletions approval.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ type approvalEnvironment struct {
issueBody string
issueApprovers []string
minimumApprovals int
targetRepoOwner string
targetRepoName string
}

func newApprovalEnvironment(client *github.Client, repoFullName, repoOwner string, runID int, approvers []string, minimumApprovals int, issueTitle, issueBody string) (*approvalEnvironment, error) {
func newApprovalEnvironment(client *github.Client, repoFullName, repoOwner string, runID int, approvers []string, minimumApprovals int, issueTitle, issueBody string, targetRepoOwner string, targetRepoName string) (*approvalEnvironment, error) {
repoOwnerAndName := strings.Split(repoFullName, "/")
if len(repoOwnerAndName) != 2 {
return nil, fmt.Errorf("repo owner and name in unexpected format: %s", repoFullName)
Expand All @@ -40,6 +42,8 @@ func newApprovalEnvironment(client *github.Client, repoFullName, repoOwner strin
minimumApprovals: minimumApprovals,
issueTitle: issueTitle,
issueBody: issueBody,
targetRepoOwner: targetRepoOwner,
targetRepoName: targetRepoName,
}, nil
}

Expand Down Expand Up @@ -77,13 +81,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,
Expand Down
26 changes: 18 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"os/signal"
"strconv"
"strings"
"time"

"github.com/google/go-github/v43/github"
Expand All @@ -16,14 +17,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
Expand All @@ -34,7 +35,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
Expand All @@ -52,15 +53,15 @@ 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 {
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})
_, _, 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
Expand All @@ -72,15 +73,15 @@ func newCommentLoopChannel(ctx context.Context, apprv *approvalEnvironment, clie
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{
_, _, 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)
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
Expand Down Expand Up @@ -149,6 +150,9 @@ func main() {
os.Exit(1)
}

targetRepoOwner := os.Getenv("target-repository-owner")
targetRepoName := os.Getenv("target-repository")

repoFullName := os.Getenv(envVarRepoFullName)
runID, err := strconv.Atoi(os.Getenv(envVarRunID))
if err != nil {
Expand All @@ -157,6 +161,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 {
Expand All @@ -181,7 +191,7 @@ func main() {
os.Exit(1)
}
}
apprv, err := newApprovalEnvironment(client, repoFullName, repoOwner, runID, approvers, minimumApprovals, issueTitle, issueBody)
apprv, err := newApprovalEnvironment(client, repoFullName, repoOwner, runID, approvers, minimumApprovals, issueTitle, issueBody, targetRepoOwner, targetRepoName)
if err != nil {
fmt.Printf("error creating approval environment: %v\n", err)
os.Exit(1)
Expand Down