()
| 172 | } |
| 173 | |
| 174 | func (c *Checker) update() (r Result, err error) { |
| 175 | ctx, cancel := context.WithTimeout(c.ctx, c.opts.UpdateTimeout) |
| 176 | defer cancel() |
| 177 | |
| 178 | c.log.Debug(c.ctx, "checking for update") |
| 179 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.opts.URL, nil) |
| 180 | if err != nil { |
| 181 | return r, xerrors.Errorf("new request: %w", err) |
| 182 | } |
| 183 | resp, err := c.opts.Client.Do(req) |
| 184 | if err != nil { |
| 185 | return r, xerrors.Errorf("client do: %w", err) |
| 186 | } |
| 187 | defer resp.Body.Close() |
| 188 | |
| 189 | if resp.StatusCode != http.StatusOK { |
| 190 | b, _ := io.ReadAll(resp.Body) |
| 191 | return r, xerrors.Errorf("unexpected status code %d: %s", resp.StatusCode, b) |
| 192 | } |
| 193 | |
| 194 | var rr github.RepositoryRelease |
| 195 | err = json.NewDecoder(resp.Body).Decode(&rr) |
| 196 | if err != nil { |
| 197 | return r, xerrors.Errorf("json decode: %w", err) |
| 198 | } |
| 199 | |
| 200 | r = Result{ |
| 201 | Checked: time.Now(), |
| 202 | Version: rr.GetTagName(), |
| 203 | URL: rr.GetHTMLURL(), |
| 204 | } |
| 205 | c.log.Debug(ctx, "update check result", slog.F("latest_version", r.Version)) |
| 206 | |
| 207 | b, err := json.Marshal(r) |
| 208 | if err != nil { |
| 209 | return r, xerrors.Errorf("json marshal result: %w", err) |
| 210 | } |
| 211 | |
| 212 | // nolint:gocritic // Inserting the last update check is a system function. |
| 213 | err = c.db.UpsertLastUpdateCheck(dbauthz.AsSystemRestricted(ctx), string(b)) |
| 214 | if err != nil { |
| 215 | return r, err |
| 216 | } |
| 217 | |
| 218 | return r, nil |
| 219 | } |
| 220 | |
| 221 | func (c *Checker) notifyIfNewer(prev, next Result) { |
| 222 | if (prev.Version == "" && next.Version != "") || semver.Compare(next.Version, prev.Version) > 0 { |
no test coverage detected