feat(ops/gerrit-webhook-to-irccat): notify when CLs are undrafted

- Extend the notification template to handle `wip-state-changed` events where a change is undrafted (i.e., `.Change.Wip` is false or not present).
- Add test cases for undrafting (should notify) and re-drafting (should not notify).
- Ensure correct handling of `.Changer.Username` for undraft notifications.
- Update Go module dependencies for test coverage. (`go mod tidy`)

This allows the IRC bot to notify when a change is moved out of
WIP/draft state, improving visibility for ready-for-review CLs.

Fixes #167.

Change-Id: I6a6a69642369726c3bd9f523ae025c34dba8c4aa
Reviewed-on: https://cl.snix.dev/c/snix/+/30641
Reviewed-by: Oleksandr Knyshuk <olk@disr.it>
Tested-by: besadii
Reviewed-by: Florian Klink <flokli@flokli.de>
This commit is contained in:
Oleksandr Knyshuk 2025-08-04 14:20:56 +02:00
parent 2a1cd31d52
commit 8d0ae4f7ae
4 changed files with 10 additions and 7 deletions

View file

@ -6,6 +6,7 @@ require (
github.com/andygrunwald/go-gerrit v1.0.0
github.com/coreos/go-systemd/v22 v22.5.0
github.com/samber/slog-http v1.6.0
github.com/stretchr/testify v1.10.0
golang.org/x/sync v0.13.0
)
@ -13,7 +14,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.10.0 // indirect
go.opentelemetry.io/otel v1.29.0 // indirect
go.opentelemetry.io/otel/trace v1.29.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View file

@ -15,8 +15,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/samber/slog-http v1.6.0 h1:+rD5QtOWGTcFT7jq8Yf0EgGy87krv0pcgh9jtWkrqjQ=
github.com/samber/slog-http v1.6.0/go.mod h1:PAcQQrYFo5KM7Qbk50gNNwKEAMGCyfsw6GN5dI0iv9g=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
@ -26,6 +24,7 @@ go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+M
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -21,10 +21,6 @@ import (
gerritStreams "github.com/andygrunwald/go-gerrit/streams"
)
// TODO:
// {"submitter":{"name":"Florian Klink","email":"flokli@flokli.de","username":"flokli"},"refUpdate":{"oldRev":"6097f070f549df94339a2b90b2e8670195c99ec3","newRev":"b339defea41b329aa33d80dcaa22623daeb040b6","refName":"refs/changes/25/30525/meta","project":"snix"},"type":"ref-updated","eventCreatedOn":1747336314}
// {"changer":{"name":"Florian Klink","email":"flokli@flokli.de","username":"flokli"},"patchSet":{"number":1,"revision":"ede307a009aa0b1eb62e9f18b7bf1f26e9fc98a9","parents":["9f8fb55318f2bafb37e4587fa4b6c793b2b540c0"],"ref":"refs/changes/25/30525/1","uploader":{"name":"Florian Klink","email":"flokli@flokli.de","username":"flokli"},"createdOn":1747335735,"author":{"name":"Florian Klink","email":"flokli@flokli.de","username":"flokli"},"kind":"REWORK","sizeInsertions":11,"sizeDeletions":1545},"change":{"project":"snix","branch":"canon","id":"If8faecdd018b45dd087b7332fe3d3a8280947358","number":30525,"subject":"fix(ops): drop clbot","owner":{"name":"Florian Klink","email":"flokli@flokli.de","username":"flokli"},"url":"https://cl.snix.dev/c/snix/+/30525","commitMessage":"fix(ops): drop clbot\n\nThis removes the old clbot, which kept an SSH connection to gerrit open.\n\nChange-Id: If8faecdd018b45dd087b7332fe3d3a8280947358\n","createdOn":1747335735,"status":"NEW"},"project":"snix","refName":"refs/heads/canon","changeKey":{"id":"If8faecdd018b45dd087b7332fe3d3a8280947358"},"type":"wip-state-changed","eventCreatedOn":1747336314}
var logger *slog.Logger
var tmplStr = `{{- if eq .Type "patchset-created" -}}
{{- if (and (eq .PatchSet.Number 1) (eq .Change.Wip false) ) -}}
@ -36,6 +32,10 @@ var tmplStr = `{{- if eq .Type "patchset-created" -}}
{{- else -}}
#snix CL/{{.Change.Number}} applied by {{.Change.Owner.Username}} - {{.Change.Subject}} - {{.Change.URL}}
{{- end -}}
{{- else if eq .Type "wip-state-changed" -}}
{{- if eq .Change.Wip false -}}
#snix CL/{{.Change.Number}} undrafted by {{.Changer.Username}} - {{.Change.Subject}} - {{.Change.URL}}
{{- end -}}
{{- end -}}`
var tmpl = template.Must(template.New("msg").Parse(tmplStr))

View file

@ -21,6 +21,10 @@ var jsonMsgs = []struct {
"#snix CL/30605 applied by jade - fix(ops/gerrit): send mail with the triggering user's name on it - https://cl.snix.dev/c/snix/+/30605"},
{"{\"submitter\":{\"name\":\"clbot\",\"username\":\"clbot\"},\"newRev\":\"afec95e269e2d59e10fb205eb793d7261b638dc2\",\"patchSet\":{\"number\":2,\"revision\":\"099f14194bcee28133af01a6e324b2fe4ecccd7c\",\"parents\":[\"9942014989bcc56b1a302ef6eb2b9f2e2aecccb8\"],\"ref\":\"refs/changes/99/30599/2\",\"uploader\":{\"name\":\"clbot\",\"username\":\"clbot\"},\"createdOn\":1751906446,\"author\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"kind\":\"NO_CODE_CHANGE\",\"sizeInsertions\":20,\"sizeDeletions\":0},\"change\":{\"project\":\"snix\",\"branch\":\"canon\",\"id\":\"I449101cfda7c8a728d3e2f3be71dee00be780ec3\",\"number\":30599,\"subject\":\"doc(README): point to website once more\",\"owner\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"url\":\"https://cl.snix.dev/c/snix/+/30599\",\"commitMessage\":\"doc(README): point to website once more\\n\\nThere\\u0027s no point in replicating redundant information in many different\\nplaces. Add some more pointers and encouragement to read the docs where\\nthey live.\\n\\nChange-Id: I449101cfda7c8a728d3e2f3be71dee00be780ec3\\nReviewed-on: https://cl.snix.dev/c/snix/+/30599\\nTested-by: besadii\\nReviewed-by: Vova Kryachko \\u003cv.kryachko@gmail.com\\u003e\\nAutosubmit: Florian Klink \\u003cflokli@flokli.de\\u003e\\n\",\"createdOn\":1751899755,\"status\":\"MERGED\"},\"project\":{\"name\":\"snix\"},\"refName\":\"refs/heads/canon\",\"changeKey\":{\"key\":\"I449101cfda7c8a728d3e2f3be71dee00be780ec3\"},\"type\":\"change-merged\",\"eventCreatedOn\":1751906446}",
"#snix CL/30599 by flokli autosubmitted - doc(README): point to website once more - https://cl.snix.dev/c/snix/+/30599"},
{"{\"changer\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"patchSet\":{\"number\":5,\"revision\":\"944b6f97be4cad910f7a831a9a24e5d3da06d77b\",\"parents\":[\"424d56733e9254dc4609ab2abed2b1ea24e7f514\"],\"ref\":\"refs/changes/28/30628/5\",\"uploader\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"createdOn\":1753962503,\"author\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"kind\":\"TRIVIAL_REBASE\",\"sizeInsertions\":16,\"sizeDeletions\":3},\"change\":{\"project\":\"snix\",\"branch\":\"canon\",\"id\":\"I1ae84e743281125ecbdc98cdb4f2adf5a96905a7\",\"number\":30628,\"subject\":\"chore(3p/nixpkgs): bump channels (2025-07-31)\",\"owner\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"url\":\"https://cl.snix.dev/c/snix/+/30628\",\"commitMessage\":\"chore(3p/nixpkgs): bump channels (2025-07-31)\\n\\nChange-Id: I1ae84e743281125ecbdc98cdb4f2adf5a96905a7\\n\",\"createdOn\":1753953838,\"status\":\"NEW\"},\"project\":\"snix\",\"refName\":\"refs/heads/canon\",\"changeKey\":{\"id\":\"I1ae84e743281125ecbdc98cdb4f2adf5a96905a7\"},\"type\":\"wip-state-changed\",\"eventCreatedOn\":1753963017}",
"#snix CL/30628 undrafted by flokli - chore(3p/nixpkgs): bump channels (2025-07-31) - https://cl.snix.dev/c/snix/+/30628"},
{"{\"changer\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"patchSet\":{\"number\":5,\"revision\":\"944b6f97be4cad910f7a831a9a24e5d3da06d77b\",\"parents\":[\"424d56733e9254dc4609ab2abed2b1ea24e7f514\"],\"ref\":\"refs/changes/28/30628/5\",\"uploader\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"createdOn\":1753962503,\"author\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"kind\":\"TRIVIAL_REBASE\",\"sizeInsertions\":16,\"sizeDeletions\":3},\"change\":{\"project\":\"snix\",\"branch\":\"canon\",\"id\":\"I1ae84e743281125ecbdc98cdb4f2adf5a96905a7\",\"number\":30628,\"subject\":\"chore(3p/nixpkgs): bump channels (2025-07-31)\",\"owner\":{\"name\":\"Florian Klink\",\"email\":\"flokli@flokli.de\",\"username\":\"flokli\"},\"url\":\"https://cl.snix.dev/c/snix/+/30628\",\"commitMessage\":\"chore(3p/nixpkgs): bump channels (2025-07-31)\\n\\nChange-Id: I1ae84e743281125ecbdc98cdb4f2adf5a96905a7\\n\",\"createdOn\":1753953838,\"status\":\"NEW\",\"wip\":true},\"project\":\"snix\",\"refName\":\"refs/heads/canon\",\"changeKey\":{\"id\":\"I1ae84e743281125ecbdc98cdb4f2adf5a96905a7\"},\"type\":\"wip-state-changed\",\"eventCreatedOn\":1753963011}",
""},
}
func TestParseChangeProposed(t *testing.T) {