From bd4e06d2f100c296396bbdee6d219d589d618a20 Mon Sep 17 00:00:00 2001 From: Arijit Das Date: Fri, 17 Sep 2021 20:58:10 +0530 Subject: [PATCH] chore(CI): Check PR body and title. (#1786) * chore(CI): Check PR body and title. * Trigger CI * Fix regex. --- .github/PULL_REQUEST/pull_request.go | 16 ++++++++ .github/workflows/checks.yml | 15 +++++++- lib/utils/pull_request.go | 44 ++++++++++++++++++++++ lib/utils/pull_request_test.go | 55 ++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 .github/PULL_REQUEST/pull_request.go create mode 100644 lib/utils/pull_request.go create mode 100644 lib/utils/pull_request_test.go diff --git a/.github/PULL_REQUEST/pull_request.go b/.github/PULL_REQUEST/pull_request.go new file mode 100644 index 0000000000..9b1d69c124 --- /dev/null +++ b/.github/PULL_REQUEST/pull_request.go @@ -0,0 +1,16 @@ +package main + +import ( + "os" + + "github.com/ChainSafe/gossamer/lib/utils" +) + +func main() { + title := os.Getenv("RAW_TITLE") + body := os.Getenv("RAW_BODY") + err := utils.CheckPRDescription(title, body) + if err != nil { + os.Exit(1) + } +} diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 29f278a3d2..a30a34aab5 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -27,4 +27,17 @@ jobs: - uses: actions/checkout@v2 - name: Run go vet - run: go vet ./... \ No newline at end of file + run: go vet ./... + + check-description: + name: Checks PR has title and body description + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Checks PR has title and body description + run: | + go run .github/PULL_REQUEST/pull_request.go + + env: + RAW_TITLE: ${{ github.event.pull_request.title }} + RAW_BODY: ${{ github.event.pull_request.body }} \ No newline at end of file diff --git a/lib/utils/pull_request.go b/lib/utils/pull_request.go new file mode 100644 index 0000000000..f14f81c988 --- /dev/null +++ b/lib/utils/pull_request.go @@ -0,0 +1,44 @@ +package utils + +import ( + "fmt" + "regexp" + "strings" +) + +const ( + titleRegex = `[A-Za-z]+\([A-Za-z/]+\):.+[A-Za-z]+` + bodyRegex = `## Changes.*- .*[A-Za-z0-9].*## Tests.*[A-Za-z].*## Issues.*- .*[A-Za-z0-9].*## Primary Reviewer.*- @.+[A-Za-z0-9].*` +) + +// CheckPRDescription matches the PR title and body according to the PR template. +func CheckPRDescription(title, body string) error { + match, err := regexp.MatchString(titleRegex, title) + if err != nil || !match { + return fmt.Errorf("title pattern is not valid: %w match %t", err, match) + } + + var bodyData string + // Remove comment from PR body. + for { + start := strings.Index(body, "") + if start < 0 || end < 0 { + break + } + + bodyData = bodyData + body[:start] + body = body[end+4:] + } + bodyData = bodyData + body + + lineSplit := strings.Split(bodyData, "\n") + joinedLine := strings.Join(lineSplit, "") + + // Regex for body data + match, err = regexp.MatchString(bodyRegex, joinedLine) + if err != nil || !match { + return fmt.Errorf("body pattern is not valid: %w match %t", err, match) + } + return nil +} diff --git a/lib/utils/pull_request_test.go b/lib/utils/pull_request_test.go new file mode 100644 index 0000000000..8cd7cf4cc5 --- /dev/null +++ b/lib/utils/pull_request_test.go @@ -0,0 +1,55 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_PR_Checks(t *testing.T) { + tests := []struct { + title string + body string + valid bool + }{ + { + title: "", + body: "", + valid: false, + }, + { + title: "abc(abc): abc", + body: "", + valid: false, + }, + { + title: `feat(dot/rpc): implement chain_subscribeAllHeads RPC`, + body: `## Changes\n\n\n\n- changes for demo :123\n\n## Tests\n\n\n\n- tests for demo:123{}\n\n## Issues\n\n\n\n- issues for demo:43434\n\n## Primary Reviewer\n\n\n\n- @noot for demo:12`, + valid: true, + }, + { + title: "abc(): abc", + body: "", + valid: false, + }, + { + title: "(abc): abc", + body: "", + valid: false, + }, + { + title: "abc(abc):", + body: "", + valid: false, + }, + } + + for _, test := range tests { + err := CheckPRDescription(test.title, test.body) + if test.valid { + require.NoError(t, err, "title", test.title, "body", test.body) + } else { + require.Error(t, err, "title", test.title, "body", test.body) + } + } +}