mirror of
https://github.com/lukaszraczylo/ghtracker.git
synced 2026-10-12 00:45:38 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78a6723143 |
@@ -96,7 +96,7 @@ actions:
|
||||
|
||||
### Automatic actions
|
||||
|
||||
An action with `auto: true` fires without a click. After every scan, and once at startup, the server sends the webhook for each current alert whose kind is in `kinds`. It sends once per action, repo, alert URL and head commit. A new commit on a pull request is a new send.
|
||||
An action with `auto: true` fires without a click. After every scan, after every single-repository rescan, and once at startup, the server sends the webhook for each current alert whose kind is in `kinds`. It sends once per action, repo, alert URL and head commit. A new commit on a pull request is a new send.
|
||||
|
||||
```yaml
|
||||
actions:
|
||||
|
||||
@@ -119,10 +119,13 @@ func (c *Collector) OnRefresh(fn func(context.Context, View)) { c.onRefresh = ap
|
||||
|
||||
func (c *Collector) refreshAndNotify(ctx context.Context) {
|
||||
c.Refresh(ctx)
|
||||
if len(c.onRefresh) == 0 || ctx.Err() != nil {
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
v := c.View()
|
||||
c.notify(ctx, c.View())
|
||||
}
|
||||
|
||||
func (c *Collector) notify(ctx context.Context, v View) {
|
||||
for _, fn := range c.onRefresh {
|
||||
fn(ctx, v)
|
||||
}
|
||||
@@ -239,7 +242,12 @@ func (c *Collector) RefreshRepo(ctx context.Context, name string) (View, error)
|
||||
c.mu.Lock()
|
||||
c.repos[canon] = r
|
||||
c.mu.Unlock()
|
||||
return c.View(), nil
|
||||
v := c.View()
|
||||
if len(c.onRefresh) > 0 {
|
||||
// The request context ends with the response, which must not wait for webhooks.
|
||||
go c.notify(context.WithoutCancel(ctx), v)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (c *Collector) configured(name string) (string, bool) {
|
||||
|
||||
@@ -519,3 +519,37 @@ func TestPROpenDoesNotChangeCounts(t *testing.T) {
|
||||
t.Fatalf("view = %+v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshRepoRunsRefreshHooksWithTheNewView(t *testing.T) {
|
||||
f := &fakeFetcher{fn: func(name string) (model.Repo, error) {
|
||||
return model.Repo{FullName: name, URL: "u", Issues: make([]model.Issue, 3)}, nil
|
||||
}}
|
||||
c := newCollector(f, "o/a")
|
||||
got := make(chan View, 1)
|
||||
c.OnRefresh(func(_ context.Context, v View) { got <- v })
|
||||
if _, err := c.RefreshRepo(context.Background(), "o/a"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
select {
|
||||
case v := <-got:
|
||||
if len(v.Repos) != 1 || len(v.Repos[0].Issues) != 3 {
|
||||
t.Fatalf("hook saw a stale view: %+v", v.Repos)
|
||||
}
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("refresh hook did not run after a repository refresh")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshRepoFailureSkipsRefreshHooks(t *testing.T) {
|
||||
c := newCollector(&fakeFetcher{fn: func(string) (model.Repo, error) { return model.Repo{}, errors.New("nope") }}, "o/a")
|
||||
called := make(chan struct{}, 1)
|
||||
c.OnRefresh(func(context.Context, View) { called <- struct{}{} })
|
||||
if _, err := c.RefreshRepo(context.Background(), "unknown/x"); err == nil {
|
||||
t.Fatal("unknown repository must fail")
|
||||
}
|
||||
select {
|
||||
case <-called:
|
||||
t.Fatal("hook ran for a refused refresh")
|
||||
case <-time.After(200 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user