Compare commits

..
2 Commits
Author SHA1 Message Date
github-actions[bot]andGitHub 6b08d09431 chore(deps): update dependencies
Automated dependency update. All tests passed.
2026-10-05 03:22:21 +00:00
lukaszraczylo 78a6723143 fix(web): run automatic actions after a repository rescan
The rescan button of one repository now triggers automatic actions too. The webhook calls run in the background so the response does not wait for them.
2026-10-05 01:57:05 +01:00
4 changed files with 95 additions and 53 deletions
+1 -1
View File
@@ -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:
+11 -3
View File
@@ -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) {
+34
View File
@@ -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):
}
}
+49 -49
View File
@@ -25,7 +25,7 @@ importers:
version: 3.3.3(@fortawesome/[email protected])([email protected]([email protected]))
'@lucide/vue':
specifier: ^1.49.0
version: 1.49.0([email protected]([email protected]))
version: 1.50.0([email protected]([email protected]))
'@vueuse/core':
specifier: ^15.0.0
version: 15.0.0([email protected]([email protected]))
@@ -50,7 +50,7 @@ importers:
devDependencies:
'@eslint/js':
specifier: ^10.0.1
version: 10.0.1([email protected]1.0([email protected]))
version: 10.0.1([email protected]2.0([email protected]))
'@tailwindcss/vite':
specifier: ^4.3.3
version: 4.3.3([email protected](@types/[email protected])([email protected]))
@@ -65,10 +65,10 @@ importers:
version: 2.5.1(@vue/[email protected])(@vue/[email protected])([email protected]([email protected]))
eslint:
specifier: ^10.11.0
version: 10.11.0([email protected])
version: 10.12.0([email protected])
eslint-plugin-vue:
specifier: ^10.11.1
version: 10.11.1(@typescript-eslint/[email protected]([email protected]1.0([email protected]))([email protected]))([email protected]1.0([email protected]))([email protected]([email protected]1.0([email protected])))
version: 10.11.1(@typescript-eslint/[email protected]([email protected]2.0([email protected]))([email protected]))([email protected]2.0([email protected]))([email protected]([email protected]2.0([email protected])))
globals:
specifier: ^17.12.0
version: 17.13.0
@@ -86,7 +86,7 @@ importers:
version: 5.9.3
typescript-eslint:
specifier: ^8.70.1
version: 8.71.0([email protected]1.0([email protected]))([email protected])
version: 8.71.0([email protected]2.0([email protected]))([email protected])
vite:
specifier: ^8.3.1
version: 8.3.2(@types/[email protected])([email protected])
@@ -95,7 +95,7 @@ importers:
version: 5.0.3(@types/[email protected])([email protected])([email protected](@types/[email protected])([email protected]))
vue-tsc:
specifier: ^3.3.11
version: 3.3.11([email protected])
version: 3.3.12([email protected])
packages:
@@ -248,8 +248,8 @@ packages:
'@keyv/[email protected]':
resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==}
'@lucide/vue@1.49.0':
resolution: {integrity: sha512-7xS5gYnLoIx0jlmlRE3Rb71fIHaNqhVBiKMpOlqrYt6nMPy3C/62HJHo5XNsV3HTK+9l3M0hXICrIA7S5v6y5Q==}
'@lucide/vue@1.50.0':
resolution: {integrity: sha512-/cYAYqHIMUcVbhGYPk+GqgPqlqTKCFfyGrpXvH/6z5v7sWRoWBHViYwO3cNgmupZCBY+4WB016wN6CkXNcy0Yw==}
peerDependencies:
vue: '>=3.0.1'
@@ -605,8 +605,8 @@ packages:
'@vue/[email protected]':
resolution: {integrity: sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==}
'@vue/[email protected]1':
resolution: {integrity: sha512-QJmpliwAVpC/OxubIByPAhNzsQPRc8/gxlN2qnVzVfIMjMDz/9RnXRFoetjz5yEgXVXyp4LqhXq3V53PjmNzFw==}
'@vue/[email protected]2':
resolution: {integrity: sha512-k7uIKR0n4CBidk233y7cac9osnDQ5WRidTl6nsrNvpZ3nf8cx9iJxRVsRzVsoPRHbowT/iKgGMTS9RGov3jeIA==}
'@vue/[email protected]':
resolution: {integrity: sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==}
@@ -806,8 +806,8 @@ packages:
resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
[email protected]1.0:
resolution: {integrity: sha512-P7a6UEEqb9G95MYAtqkmsTbVXIYyzIfl6NGOIJk162PaahFxFyeGcrlXYFSiagECg4sEm8IseJdZBKR3rx6MsQ==}
[email protected]2.0:
resolution: {integrity: sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
hasBin: true
peerDependencies:
@@ -1435,8 +1435,8 @@ packages:
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
[email protected]1:
resolution: {integrity: sha512-gOb0B9rtU2+f1dszwPqSH5kAieIF9ReeLhD3kSRNHv5WZZUQz/JdVXW0RTdqhNTMlQkqKzrTTviqKr/4FYZraQ==}
[email protected]2:
resolution: {integrity: sha512-kbpaz18O9jPVkXVHD1BEjpUXM6WhXSu+62L1sGGr6Wbzd8GbvkBQWjoj3KZ/C0aq2MZllce7UdtWzwCIYsBMGA==}
hasBin: true
peerDependencies:
typescript: '>=5.0.0'
@@ -1514,9 +1514,9 @@ snapshots:
hashery: 1.5.1
keyv: 5.6.0
'@eslint-community/[email protected]([email protected]1.0([email protected]))':
'@eslint-community/[email protected]([email protected]2.0([email protected]))':
dependencies:
eslint: 10.11.0([email protected])
eslint: 10.12.0([email protected])
eslint-visitor-keys: 3.4.3
'@eslint-community/[email protected]': {}
@@ -1537,9 +1537,9 @@ snapshots:
dependencies:
'@types/json-schema': 7.0.15
'@eslint/[email protected]([email protected]1.0([email protected]))':
'@eslint/[email protected]([email protected]2.0([email protected]))':
optionalDependencies:
eslint: 10.11.0([email protected])
eslint: 10.12.0([email protected])
'@eslint/[email protected]': {}
@@ -1638,7 +1638,7 @@ snapshots:
'@keyv/[email protected]': {}
'@lucide/vue@1.49.0([email protected]([email protected]))':
'@lucide/vue@1.50.0([email protected]([email protected]))':
dependencies:
vue: 3.5.43([email protected])
@@ -1797,15 +1797,15 @@ snapshots:
dependencies:
'@types/node': 26.6.4
'@typescript-eslint/[email protected](@typescript-eslint/[email protected]([email protected]1.0([email protected]))([email protected]))([email protected]1.0([email protected]))([email protected])':
'@typescript-eslint/[email protected](@typescript-eslint/[email protected]([email protected]2.0([email protected]))([email protected]))([email protected]2.0([email protected]))([email protected])':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 8.71.0([email protected]1.0([email protected]))([email protected])
'@typescript-eslint/parser': 8.71.0([email protected]2.0([email protected]))([email protected])
'@typescript-eslint/scope-manager': 8.71.0
'@typescript-eslint/type-utils': 8.71.0([email protected]1.0([email protected]))([email protected])
'@typescript-eslint/utils': 8.71.0([email protected]1.0([email protected]))([email protected])
'@typescript-eslint/type-utils': 8.71.0([email protected]2.0([email protected]))([email protected])
'@typescript-eslint/utils': 8.71.0([email protected]2.0([email protected]))([email protected])
'@typescript-eslint/visitor-keys': 8.71.0
eslint: 10.11.0([email protected])
eslint: 10.12.0([email protected])
ignore: 7.0.11
natural-compare: 1.4.0
ts-api-utils: 2.5.0([email protected])
@@ -1813,14 +1813,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]([email protected]1.0([email protected]))([email protected])':
'@typescript-eslint/[email protected]([email protected]2.0([email protected]))([email protected])':
dependencies:
'@typescript-eslint/scope-manager': 8.71.0
'@typescript-eslint/types': 8.71.0
'@typescript-eslint/typescript-estree': 8.71.0([email protected])
'@typescript-eslint/visitor-keys': 8.71.0
debug: 4.4.3
eslint: 10.11.0([email protected])
eslint: 10.12.0([email protected])
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -1843,13 +1843,13 @@ snapshots:
dependencies:
typescript: 5.9.3
'@typescript-eslint/[email protected]([email protected]1.0([email protected]))([email protected])':
'@typescript-eslint/[email protected]([email protected]2.0([email protected]))([email protected])':
dependencies:
'@typescript-eslint/types': 8.71.0
'@typescript-eslint/typescript-estree': 8.71.0([email protected])
'@typescript-eslint/utils': 8.71.0([email protected]1.0([email protected]))([email protected])
'@typescript-eslint/utils': 8.71.0([email protected]2.0([email protected]))([email protected])
debug: 4.4.3
eslint: 10.11.0([email protected])
eslint: 10.12.0([email protected])
ts-api-utils: 2.5.0([email protected])
typescript: 5.9.3
transitivePeerDependencies:
@@ -1872,13 +1872,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/[email protected]([email protected]1.0([email protected]))([email protected])':
'@typescript-eslint/[email protected]([email protected]2.0([email protected]))([email protected])':
dependencies:
'@eslint-community/eslint-utils': 4.10.1([email protected]1.0([email protected]))
'@eslint-community/eslint-utils': 4.10.1([email protected]2.0([email protected]))
'@typescript-eslint/scope-manager': 8.71.0
'@typescript-eslint/types': 8.71.0
'@typescript-eslint/typescript-estree': 8.71.0([email protected])
eslint: 10.11.0([email protected])
eslint: 10.12.0([email protected])
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -1962,7 +1962,7 @@ snapshots:
'@vue/[email protected]': {}
'@vue/[email protected]1':
'@vue/[email protected]2':
dependencies:
'@volar/language-core': 2.4.28
'@vue/compiler-dom': 3.5.43
@@ -2129,18 +2129,18 @@ snapshots:
[email protected]: {}
[email protected](@typescript-eslint/[email protected]([email protected]1.0([email protected]))([email protected]))([email protected]1.0([email protected]))([email protected]([email protected]1.0([email protected]))):
[email protected](@typescript-eslint/[email protected]([email protected]2.0([email protected]))([email protected]))([email protected]2.0([email protected]))([email protected]([email protected]2.0([email protected]))):
dependencies:
'@eslint-community/eslint-utils': 4.10.1([email protected]1.0([email protected]))
eslint: 10.11.0([email protected])
'@eslint-community/eslint-utils': 4.10.1([email protected]2.0([email protected]))
eslint: 10.12.0([email protected])
natural-compare: 1.4.0
nth-check: 2.1.1
postcss-selector-parser: 7.1.6
semver: 7.8.5
vue-eslint-parser: 10.4.1([email protected]1.0([email protected]))
vue-eslint-parser: 10.4.1([email protected]2.0([email protected]))
xml-name-validator: 5.0.0
optionalDependencies:
'@typescript-eslint/parser': 8.71.0([email protected]1.0([email protected]))([email protected])
'@typescript-eslint/parser': 8.71.0([email protected]2.0([email protected]))([email protected])
[email protected]:
dependencies:
@@ -2153,9 +2153,9 @@ snapshots:
[email protected]: {}
[email protected]1.0([email protected]):
[email protected]2.0([email protected]):
dependencies:
'@eslint-community/eslint-utils': 4.10.1([email protected]1.0([email protected]))
'@eslint-community/eslint-utils': 4.10.1([email protected]2.0([email protected]))
'@eslint-community/regexpp': 4.12.2
'@eslint/config-array': 0.23.5
'@eslint/config-helpers': 0.7.0
@@ -2603,13 +2603,13 @@ snapshots:
dependencies:
prelude-ls: 1.2.1
[email protected]([email protected]1.0([email protected]))([email protected]):
[email protected]([email protected]2.0([email protected]))([email protected]):
dependencies:
'@typescript-eslint/eslint-plugin': 8.71.0(@typescript-eslint/[email protected]([email protected]1.0([email protected]))([email protected]))([email protected]1.0([email protected]))([email protected])
'@typescript-eslint/parser': 8.71.0([email protected]1.0([email protected]))([email protected])
'@typescript-eslint/eslint-plugin': 8.71.0(@typescript-eslint/[email protected]([email protected]2.0([email protected]))([email protected]))([email protected]2.0([email protected]))([email protected])
'@typescript-eslint/parser': 8.71.0([email protected]2.0([email protected]))([email protected])
'@typescript-eslint/typescript-estree': 8.71.0([email protected])
'@typescript-eslint/utils': 8.71.0([email protected]1.0([email protected]))([email protected])
eslint: 10.11.0([email protected])
'@typescript-eslint/utils': 8.71.0([email protected]2.0([email protected]))([email protected])
eslint: 10.12.0([email protected])
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -2666,10 +2666,10 @@ snapshots:
dependencies:
vue: 3.5.43([email protected])
[email protected]([email protected]1.0([email protected])):
[email protected]([email protected]2.0([email protected])):
dependencies:
debug: 4.4.3
eslint: 10.11.0([email protected])
eslint: 10.12.0([email protected])
eslint-scope: 9.1.2
eslint-visitor-keys: 5.0.1
espree: 11.2.0
@@ -2678,10 +2678,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
[email protected]1([email protected]):
[email protected]2([email protected]):
dependencies:
'@volar/typescript': 2.4.28([email protected])
'@vue/language-core': 3.3.11
'@vue/language-core': 3.3.12
typescript: 5.9.3
[email protected]([email protected]):