golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.55k stars 17.61k forks source link

x/build/maintner: make it easy for interested clients to subscribe/watch for new Go releases #37577

Open dmitshur opened 4 years ago

dmitshur commented 4 years ago

There are many clients that might be interested in knowing when a new Go release is tagged, in order to take some automated action. One recent example is pkg.go.dev (see issue #37568), but there are plenty of others.

Maintner already tracks the Go repository and knows when any tags are made. Interested clients can use a maintner client (either a normal one, or a tail-only client) to easily get notified and take appropriate action.

It should be helpful to make this easier to discover and use. /cc @julieqiu @toothrot @cagedmantis

Perhaps it can be done by adding an example to maintner package documentation. Here's a starting point for an example that uses maintner.TailNetworkMutationSource to watch for all new tags created in the main Go repository and printing them to stdout:

// Tail events from the maintner server in a loop.
for {
    err := maintner.TailNetworkMutationSource(context.Background(), godata.Server, func(e maintner.MutationStreamEvent) error {
        if e.Err != nil {
            log.Printf("# ignoring err: %v\n", e.Err)
            time.Sleep(5 * time.Second)
            return nil
        }
        m := e.Mutation
        if m.Gerrit == nil || m.Gerrit.Project != "go.googlesource.com/go" {
            // Not a Gerrit event, or not the main Go repo. Skip.
            return nil
        }
        for _, r := range m.Gerrit.Refs {
            if !strings.HasPrefix(r.Ref, "refs/tags/") {
                // Not a tag. Skip.
                continue
            }
            fmt.Printf("new tag in go repo: name=%q sha1=%q\n", r.Ref[len("refs/tags/"):], r.Sha1)
        }
        return nil
    })
    log.Printf("tail error: %v; restarting\n", err)
    time.Sleep(time.Second)
}

Using a full maintner client or maintner.NewNetworkMutationSource is a little more involved because it requires preserving state, which means writing to disk or another place. But this option can be investigated too.

Finally, we can consider exposing this functionality via a higher level API, but I think it should be easier to prototype this before committing to a public API that's hard to change.

dmitshur commented 4 years ago

Also see issues #34864 and #36898.

/cc @mvdan @jmhodges