Re-mint watchpr's Gitea token when it expires
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful

Vault-minted Gitea tokens last ~1h, far less than a watch, and every poll
past expiry 401'd into a warning while watchpr looked healthy.

- retry a rejected request once with a freshly minted token
- abort the watch when the fresh token is rejected too
- poll anonymously when no token can be minted, mint only on a real 401/403
This commit is contained in:
2026-09-09 21:15:46 +10:00
parent d9645ec5e4
commit 7ef0e28e96
8 changed files with 429 additions and 22 deletions
+11 -3
View File
@@ -1,6 +1,9 @@
package agent
import "time"
import (
"fmt"
"time"
)
// PRState is a point-in-time snapshot of the PR attributes watchpr tracks.
type PRState struct {
@@ -82,8 +85,10 @@ func terminalState(st PRState) (bool, string) {
// tracked PR changes meaningfully, returning the first such change. A PR that is
// already terminal (merged/closed) at baseline is reported immediately rather
// than polled forever. Poll errors are handed to onError and never stop the
// loop; only a baseline fetch error aborts. onBaseline, if set, fires once after
// all baselines are captured and before the first tick.
// loop; a baseline fetch error and an authentication failure (the token was
// rejected and re-minting it did not help) abort instead, because a watcher that
// cannot authenticate sees nothing. onBaseline, if set, fires once after all
// baselines are captured and before the first tick.
func Watch(f StateFetcher, refs []PRRef, agentLogin string, ticks <-chan time.Time, onBaseline func(), onError func(PRRef, error)) (WatchResult, error) {
prev := make(map[string]PRState, len(refs))
for _, ref := range refs {
@@ -104,6 +109,9 @@ func Watch(f StateFetcher, refs []PRRef, agentLogin string, ticks <-chan time.Ti
key := ref.String()
cur, err := f.FetchState(ref, agentLogin)
if err != nil {
if IsAuthError(err) {
return WatchResult{}, fmt.Errorf("polling %s: %w", key, err)
}
if onError != nil {
onError(ref, err)
}