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

Feature/issue label and file preview #92

Open
wants to merge 3 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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ steps:
exclude-workflow-initiator-as-approver: false
additional-approved-words: ''
additional-denied-words: ''
labels: ''
additional-issue-body-file: '{base64}.{file extension}'
```

- `approvers` is a comma-delimited list of all required approvers. An approver can either be a user or an org team. (*Note: Required approvers must have the ability to be set as approvers in the repository. If you add an approver that doesn't have this permission then you would receive an HTTP/402 Validation Failed error when running this action*)
Expand All @@ -45,6 +47,8 @@ steps:
- `exclude-workflow-initiator-as-approver` is a boolean that indicates if the workflow initiator (determined by the `GITHUB_ACTOR` environment variable) should be filtered from the final list of approvers. This is optional and defaults to `false`. Set this to `true` to prevent users in the `approvers` list from being able to self-approve workflows.
- `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.
- `additional-denied-words` is a comma separated list of strings to set labels of issue.
- `additional-issue-body-file` is a string that will decode base64 to show the preview of the file inside body.

### Using Custom Words

Expand Down
6 changes: 6 additions & 0 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ inputs:
additional-denied-words:
description: Comma separated list of words that can be used to deny beyond the defaults.
default: ''
labels:
description: Issue labels
required: false
additional-issue-body-file:
description: The custom body for the issue to show file preview
required: false
runs:
using: docker
image: docker://ghcr.io/trstringer/manual-approval:1.9.0
67 changes: 45 additions & 22 deletions approval.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"encoding/base64"
"fmt"
"regexp"
"strings"
Expand All @@ -10,36 +11,40 @@ import (
)

type approvalEnvironment struct {
client *github.Client
repoFullName string
repo string
repoOwner string
runID int
approvalIssue *github.Issue
approvalIssueNumber int
issueTitle string
issueBody string
issueApprovers []string
minimumApprovals int
client *github.Client
repoFullName string
repo string
repoOwner string
runID int
approvalIssue *github.Issue
approvalIssueNumber int
issueTitle string
issueBody string
issueApprovers []string
minimumApprovals int
labels []string
issueBodyFilePreview 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, labels []string, issueBodyFilePreview string) (*approvalEnvironment, error) {
repoOwnerAndName := strings.Split(repoFullName, "/")
if len(repoOwnerAndName) != 2 {
return nil, fmt.Errorf("repo owner and name in unexpected format: %s", repoFullName)
}
repo := repoOwnerAndName[1]

return &approvalEnvironment{
client: client,
repoFullName: repoFullName,
repo: repo,
repoOwner: repoOwner,
runID: runID,
issueApprovers: approvers,
minimumApprovals: minimumApprovals,
issueTitle: issueTitle,
issueBody: issueBody,
client: client,
repoFullName: repoFullName,
repo: repo,
repoOwner: repoOwner,
runID: runID,
issueApprovers: approvers,
minimumApprovals: minimumApprovals,
issueTitle: issueTitle,
issueBody: issueBody,
labels: labels,
issueBodyFilePreview: issueBodyFilePreview,
}, nil
}

Expand All @@ -66,23 +71,41 @@ Respond %s to continue workflow or %s to cancel.`,
formatAcceptedWords(deniedWords),
)

if a.issueBodyFilePreview != "" {
s := strings.Split(a.issueBodyFilePreview, ".")
if len(s) == 2 {
ext := s[1]
content, err := base64.StdEncoding.DecodeString(s[0])
if err != nil {
fmt.Printf("%s\n", err.Error())
} else {
issueBody = fmt.Sprintf(`%s%s
%s
%s
%s`, "```", ext, string(content), "````", issueBody)
}
}
}

if a.issueBody != "" {
issueBody = fmt.Sprintf("%s\n\n%s", a.issueBody, issueBody)
}

var err error
fmt.Printf(
"Creating issue in repo %s/%s with the following content:\nTitle: %s\nApprovers: %s\nBody:\n%s\n",
"Creating issue in repo %s/%s with the following content:\nTitle: %s\nApprovers: %s\nLabels: %s\nBody:\n%s\n",
a.repoOwner,
a.repo,
issueTitle,
a.issueApprovers,
a.labels,
issueBody,
)
a.approvalIssue, _, err = a.client.Issues.Create(ctx, a.repoOwner, a.repo, &github.IssueRequest{
Title: &issueTitle,
Body: &issueBody,
Assignees: &a.issueApprovers,
Labels: &a.labels,
})
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const (
envVarExcludeWorkflowInitiatorAsApprover string = "INPUT_EXCLUDE-WORKFLOW-INITIATOR-AS-APPROVER"
envVarAdditionalApprovedWords string = "INPUT_ADDITIONAL-APPROVED-WORDS"
envVarAdditionalDeniedWords string = "INPUT_ADDITIONAL-DENIED-WORDS"
envVarLabels string = "INPUT_LABELS"
envVarAdditionalIssueBodyFile string = "INPUT_ADDITIONAL-ISSUE-BODY-FILE"
)

var (
Expand Down
5 changes: 4 additions & 1 deletion 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 Down Expand Up @@ -172,6 +173,8 @@ func main() {

issueTitle := os.Getenv(envVarIssueTitle)
issueBody := os.Getenv(envVarIssueBody)
labels := os.Getenv(envVarLabels)
issueBodyFilePreview := os.Getenv(envVarAdditionalIssueBodyFile)
minimumApprovalsRaw := os.Getenv(envVarMinimumApprovals)
minimumApprovals := 0
if minimumApprovalsRaw != "" {
Expand All @@ -181,7 +184,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, strings.Split(labels, ","), issueBodyFilePreview)
if err != nil {
fmt.Printf("error creating approval environment: %v\n", err)
os.Exit(1)
Expand Down