Skip to content
Merged
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
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
build: pretriage triage posttriage doctext

pretriage: cmd/pretriage pkg/jiraclient pkg/query
pretriage: cmd/pretriage pkg/jiraclient pkg/query pkg/slack pkg/team
go build ./$<

triage: cmd/triage pkg/jiraclient pkg/query
triage: cmd/triage pkg/jiraclient pkg/query pkg/slack pkg/team
go build ./$<

posttriage: cmd/posttriage pkg/jiraclient pkg/query
go build ./$<

doctext: cmd/doctext pkg/jiraclient pkg/query
doctext: cmd/doctext pkg/jiraclient pkg/query pkg/slack pkg/team
go build ./$<

lint:
Expand Down
57 changes: 21 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,27 @@ Required environment variables:

* `JIRA_TOKEN`: a [Jira API token](https://issues.redhat.com/secure/ViewProfile.jspa?selectedTab=com.atlassian.pats.pats-plugin:jira-user-personal-access-tokens) of an account that can access the OCPBUGS project
* `SLACK_HOOK`: a [Slack hook](https://api.slack.com/messaging/webhooks) URL
* `TEAM_MEMBERS_DICT` is a JSON object in the form:

```json
{
"kerberos_id1": {
"slack_id": "UG65473AM",
"bz_id": "user1@example.com",
"components": ["component1"],
"jira_name": "user1",
"jira_components": ["component1/sub-component1"]
},
"kerberos_id2": {
"slack_id": "UGF8B93HA",
"bz_id": "user2@example.com",
"components": [],
"jira_name": "user2",
"jira_components": []
}
}
* `PEOPLE`: an address book. It is a YAML object in the form:

```yaml
- kerberos: user1
github_handle: ghuser
jira_name: jirauser
slack_id: U012334
- kerberos: user2
github_handle: ghuser2
jira_name: jirauser2
slack_id: U0122345
```

Optional environment variable: `TEAM_VACATION` in the form:

```json
[
{
"kerberos": "jdoe",
"start": "2022-01-01",
"end": "2022-01-15"
},
{
"kerberos": "jdoe",
"start": "2022-06-12",
"end": "2022-06-15"
}
]
* `TEAM`: an object containing team members, referencing the `kerberos` property of PEOPLE. It is a YAML object in the form:

```yaml
user1:
bug_triage: true
leave:
- start: 2024-11-21
end: 2025-02-28
```

### Local testing
Expand All @@ -82,7 +67,7 @@ Required environment variables:

* `JIRA_TOKEN`: a [Jira API token](https://issues.redhat.com/secure/ViewProfile.jspa?selectedTab=com.atlassian.pats.pats-plugin:jira-user-personal-access-tokens) of an account that can access the OCPBUGS project
* `SLACK_HOOK`: a [Slack hook](https://api.slack.com/messaging/webhooks) URL
* `TEAM_MEMBERS_DICT` is a JSON object in the form described [above][pretriage].
* `PEOPLE` and `TEAM` described [above][pretriage].

## posttriage

Expand Down Expand Up @@ -112,4 +97,4 @@ Required environment variables:

* `JIRA_TOKEN`: a [Jira API token](https://issues.redhat.com/secure/ViewProfile.jspa?selectedTab=com.atlassian.pats.pats-plugin:jira-user-personal-access-tokens) of an account that can access the OCPBUGS project
* `SLACK_HOOK`: a [Slack hook](https://api.slack.com/messaging/webhooks) URL
* `TEAM_MEMBERS_DICT` is a JSON object in the form:
* `PEOPLE` and `TEAM` described [above][pretriage].
45 changes: 45 additions & 0 deletions cmd/check/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// This program checks that the variables are syntactically correct.
package main

import (
"fmt"
"log"
"os"
"strings"

"github.com/shiftstack/bugwatcher/pkg/team"
)

var (
PEOPLE = os.Getenv("PEOPLE")
TEAM = os.Getenv("TEAM")
)

func main() {
people, err := team.Load(strings.NewReader(PEOPLE), strings.NewReader(TEAM))
if err != nil {
log.Fatalf("Error loading team members: %v", err)
}

fmt.Printf("Found %d people:\n", len(people))
}

func init() {
log.SetFlags(log.Ldate | log.Ltime | log.LUTC)

ex_usage := false
if PEOPLE == "" {
ex_usage = true
log.Print("Required environment variable not found: PEOPLE")
}

if TEAM == "" {
ex_usage = true
log.Print("Required environment variable not found: TEAM")
}

if ex_usage {
log.Print("Exiting.")
os.Exit(64)
}
}
42 changes: 28 additions & 14 deletions cmd/doctext/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,28 @@ import (
"github.com/shiftstack/bugwatcher/pkg/jiraclient"
"github.com/shiftstack/bugwatcher/pkg/query"
"github.com/shiftstack/bugwatcher/pkg/slack"
"github.com/shiftstack/bugwatcher/pkg/team"
)

const queryTriaged = query.ShiftStack + `AND status in ("Release Pending", Verified, ON_QA) AND "Release Note Text" is EMPTY`

var (
SLACK_HOOK = os.Getenv("SLACK_HOOK")
JIRA_TOKEN = os.Getenv("JIRA_TOKEN")
TEAM_MEMBERS_DICT = os.Getenv("TEAM_MEMBERS_DICT")
SLACK_HOOK = os.Getenv("SLACK_HOOK")
JIRA_TOKEN = os.Getenv("JIRA_TOKEN")
PEOPLE = os.Getenv("PEOPLE")
TEAM = os.Getenv("TEAM")
)

func main() {
ctx := context.Background()

var team Team
if err := team.Load(strings.NewReader(TEAM_MEMBERS_DICT)); err != nil {
log.Fatalf("error unmarshaling TEAM_MEMBERS_DICT: %v", err)
var people []team.Person
{
var err error
people, err = team.Load(strings.NewReader(PEOPLE), strings.NewReader(TEAM))
if err != nil {
log.Fatalf("error fetching team information: %v", err)
}
}

jiraClient, err := jiraclient.NewWithToken(query.JiraBaseURL, JIRA_TOKEN)
Expand Down Expand Up @@ -67,7 +73,7 @@ func main() {
log.Printf("INFO: Missing DocText for %q", issue.Key)
var assignee string
if issue.Fields.Assignee == nil {
assignee = "team"
assignee = ""
} else {
assignee = issue.Fields.Assignee.Name
}
Expand All @@ -78,12 +84,15 @@ func main() {
}
wg.Wait()

for assignee, issues := range issuesNeedingAttention {
teamMember, ok := team[assignee]
if !ok {
teamMember = team["team"]
for assigneeJiraName, issues := range issuesNeedingAttention {
var slackId string
if person, ok := team.PersonByJiraName(people, assigneeJiraName); ok {
slackId = person.Slack
} else {
slackId = team.TeamSlackId
}
if err := slackClient.Send(SLACK_HOOK, notification(issues, teamMember)); err != nil {

if err := slackClient.Send(SLACK_HOOK, notification(issues, slackId)); err != nil {
gotErrors = true
log.Print(err)
return
Expand All @@ -109,9 +118,14 @@ func init() {
log.Print("Required environment variable not found: JIRA_TOKEN")
}

if TEAM_MEMBERS_DICT == "" {
if PEOPLE == "" {
ex_usage = true
log.Print("Required environment variable not found: PEOPLE")
}

if TEAM == "" {
ex_usage = true
log.Print("Required environment variable not found: TEAM_MEMBERS_DICT")
log.Print("Required environment variable not found: TEAM")
}

if ex_usage {
Expand Down
13 changes: 4 additions & 9 deletions cmd/doctext/notify.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@ import (
"github.com/shiftstack/bugwatcher/pkg/slack"
)

func notification(issues []jira.Issue, assignee TeamMember) string {
var slackId string
if strings.HasPrefix(assignee.SlackId, "!subteam^") {
slackId = "<" + assignee.SlackId + ">"
} else {
slackId = "<@" + assignee.SlackId + ">"
}

func notification(issues []jira.Issue, slackId string) string {
var notification strings.Builder
notification.WriteString(slackId + " please check the Release Note Text of these bugs:")
notification.WriteByte('<')
notification.WriteString(slackId)
notification.WriteString("> please check the Release Note Text of these bugs:")
for _, issue := range issues {
notification.WriteByte(' ')
notification.WriteString(slack.Link(query.JiraBaseURL+"browse/"+issue.Key, issue.Key))
Expand Down
61 changes: 0 additions & 61 deletions cmd/doctext/team.go

This file was deleted.

4 changes: 2 additions & 2 deletions cmd/pretriage/assign.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
jira "github.com/andygrunwald/go-jira"
)

func assign(jiraClient *jira.Client, issue jira.Issue, assignee TeamMember) error {
res, err := jiraClient.Issue.UpdateAssignee(issue.ID, &jira.User{Name: assignee.JiraName})
func assign(jiraClient *jira.Client, issue jira.Issue, assigneeJiraName string) error {
res, err := jiraClient.Issue.UpdateAssignee(issue.ID, &jira.User{Name: assigneeJiraName})
if err != nil && res == nil {
// we only error out early if there's no response to work with
return fmt.Errorf("error while assigning bug %s: %w", issue.Key, err)
Expand Down
Loading