From 41793691c3c4eedf2667fa5f67b226a557201e67 Mon Sep 17 00:00:00 2001 From: sunny Date: Mon, 21 Oct 2024 19:50:08 +0530 Subject: [PATCH 1/4] Adding the capability to create the approval issue in another repository --- .github/workflows/ci.yaml | 17 +++++++++-------- Dockerfile | 2 +- Makefile | 3 ++- action.yaml | 2 +- approval.go | 12 ++++++++---- main.go | 27 +++++++++++++++++++-------- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a6ab720..3b5ee03 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -3,7 +3,7 @@ name: CI on: workflow_dispatch: push: - branches: + branches-ignore: - main paths-ignore: - '**/*.md' @@ -20,11 +20,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 + - name: Build - run: make build - env: - VERSION: latest - - name: Test - run: make test - - name: Lint - run: make lint + run: | + docker login --username sunny-1651 --password ${{ secrets.PAT_TOKEN }} ghcr.io + make build VERSION="latest" + # - name: Test + # run: make test + # - name: Lint + # run: make lint diff --git a/Dockerfile b/Dockerfile index 6ec73aa..2e0f321 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /var/app RUN CGO_ENABLED=0 go build -o app . FROM alpine:3.14 -LABEL org.opencontainers.image.source https://github.com/trstringer/manual-approval +LABEL org.opencontainers.image.source https://github.com/sunny-1651/manual-approval RUN apk update && apk add ca-certificates COPY --from=builder /var/app/app /var/app/app CMD ["/var/app/app"] diff --git a/Makefile b/Makefile index 3ec553a..dfe82a8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -IMAGE_REPO=ghcr.io/trstringer/manual-approval +IMAGE_REPO=ghcr.io/sunny-1651/manual-approval .PHONY: build build: @@ -7,6 +7,7 @@ build: exit 1; \ fi docker build -t $(IMAGE_REPO):$$VERSION . + docker push $(IMAGE_REPO):$$VERSION .PHONY: push push: diff --git a/action.yaml b/action.yaml index 7866c0b..9433e66 100644 --- a/action.yaml +++ b/action.yaml @@ -33,4 +33,4 @@ inputs: default: '' runs: using: docker - image: docker://ghcr.io/trstringer/manual-approval:1.9.1 + image: docker://ghcr.io/sunny-1651/manual-approval:latest diff --git a/approval.go b/approval.go index e2bb13f..be7a4ce 100644 --- a/approval.go +++ b/approval.go @@ -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) @@ -40,6 +42,8 @@ func newApprovalEnvironment(client *github.Client, repoFullName, repoOwner strin minimumApprovals: minimumApprovals, issueTitle: issueTitle, issueBody: issueBody, + targetRepoOwner: targetRepoOwner, + targetRepoName: targetRepoName, }, nil } @@ -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, diff --git a/main.go b/main.go index 5aad15e..362e47f 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "os" "os/signal" "strconv" + "strings" "time" "github.com/google/go-github/v43/github" @@ -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 @@ -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 @@ -52,7 +53,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 { @@ -60,7 +61,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 @@ -72,7 +73,7 @@ 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 { @@ -80,7 +81,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 @@ -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 { @@ -157,6 +161,13 @@ func main() { } repoOwner := os.Getenv(envVarRepoOwner) + if targetRepoName == "" || targetRepoOwner == "" { + parts := strings.SplitN(repoFullName, "/", 2) + targetRepoOwner = parts[0] + targetRepoName = parts[1] + } + fmt.Printf("repo owner: %s, name: %s \n", targetRepoOwner, targetRepoName) // debug message + ctx := context.Background() client, err := newGithubClient(ctx) if err != nil { @@ -181,7 +192,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) From 34a7ca17de76665caac4bea2b66939469f7815f2 Mon Sep 17 00:00:00 2001 From: sunny Date: Mon, 21 Oct 2024 19:56:18 +0530 Subject: [PATCH 2/4] reverting testing changes --- .github/workflows/ci.yaml | 16 ++++++++-------- Dockerfile | 2 +- Makefile | 2 +- action.yaml | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3b5ee03..0e5b792 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -3,7 +3,7 @@ name: CI on: workflow_dispatch: push: - branches-ignore: + branches: - main paths-ignore: - '**/*.md' @@ -22,10 +22,10 @@ jobs: uses: actions/checkout@v2 - name: Build - run: | - docker login --username sunny-1651 --password ${{ secrets.PAT_TOKEN }} ghcr.io - make build VERSION="latest" - # - name: Test - # run: make test - # - name: Lint - # run: make lint + run: make build + env: + VERSION: latest + - name: Test + run: make test + - name: Lint + run: make lint diff --git a/Dockerfile b/Dockerfile index 2e0f321..6ec73aa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /var/app RUN CGO_ENABLED=0 go build -o app . FROM alpine:3.14 -LABEL org.opencontainers.image.source https://github.com/sunny-1651/manual-approval +LABEL org.opencontainers.image.source https://github.com/trstringer/manual-approval RUN apk update && apk add ca-certificates COPY --from=builder /var/app/app /var/app/app CMD ["/var/app/app"] diff --git a/Makefile b/Makefile index dfe82a8..0db0b99 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -IMAGE_REPO=ghcr.io/sunny-1651/manual-approval +IMAGE_REPO=ghcr.io/trstringer/manual-approval .PHONY: build build: diff --git a/action.yaml b/action.yaml index 9433e66..7866c0b 100644 --- a/action.yaml +++ b/action.yaml @@ -33,4 +33,4 @@ inputs: default: '' runs: using: docker - image: docker://ghcr.io/sunny-1651/manual-approval:latest + image: docker://ghcr.io/trstringer/manual-approval:1.9.1 From 9a9e571090268bc1b03c0bdd5543f632a3580d7d Mon Sep 17 00:00:00 2001 From: sunny Date: Mon, 21 Oct 2024 19:57:45 +0530 Subject: [PATCH 3/4] reverting test changes contd. --- .github/workflows/ci.yaml | 2 +- Makefile | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0e5b792..5fa65b1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,7 +24,7 @@ jobs: - name: Build run: make build env: - VERSION: latest + VERSION: latest - name: Test run: make test - name: Lint diff --git a/Makefile b/Makefile index 0db0b99..3ec553a 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,6 @@ build: exit 1; \ fi docker build -t $(IMAGE_REPO):$$VERSION . - docker push $(IMAGE_REPO):$$VERSION .PHONY: push push: From 71178d613494b86429d24d2d5315dbd319311bd0 Mon Sep 17 00:00:00 2001 From: sunny Date: Mon, 21 Oct 2024 20:56:39 +0530 Subject: [PATCH 4/4] Updating readme and removing a debug line --- README.md | 20 ++++++++++++++++++++ main.go | 1 - 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 25218e9..f51948b 100644 --- a/README.md +++ b/README.md @@ -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 ✅. diff --git a/main.go b/main.go index 362e47f..240a1bf 100644 --- a/main.go +++ b/main.go @@ -166,7 +166,6 @@ func main() { targetRepoOwner = parts[0] targetRepoName = parts[1] } - fmt.Printf("repo owner: %s, name: %s \n", targetRepoOwner, targetRepoName) // debug message ctx := context.Background() client, err := newGithubClient(ctx)