// Copyright 2024 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package common import ( "context" "errors" "time" "github.com/rs/zerolog/log" "github.com/urfave/cli/v3" "go.woodpecker-ci.org/woodpecker/v3/cli/internal/config" "go.woodpecker-ci.org/woodpecker/v3/cli/update" ) var ( waitForUpdateCheck context.Context cancelWaitForUpdate context.CancelCauseFunc ) func Before(ctx context.Context, c *cli.Command) (context.Context, error) { if err := setupGlobalLogger(ctx, c); err != nil { return ctx, err } go func(context.Context) { if c.Bool("disable-update-check") { return } // Don't check for updates when the update command is executed if firstArg := c.Args().First(); firstArg == "update" { return } waitForUpdateCheck, cancelWaitForUpdate = context.WithCancelCause(context.Background()) defer cancelWaitForUpdate(errors.New("update check finished")) log.Debug().Msg("checking for updates ...") newVersion, err := update.CheckForUpdate(waitForUpdateCheck, false) //nolint:contextcheck if err != nil { log.Error().Err(err).Msgf("failed to check for updates") return } if newVersion != nil { log.Warn().Msgf("new version of woodpecker-cli is available: %s, update with: %s update", newVersion.Version, c.Root().Name) } else { log.Debug().Msgf("no update required") } }(ctx) return ctx, config.Load(ctx, c) } func After(_ context.Context, _ *cli.Command) error { if waitForUpdateCheck != nil { select { case <-waitForUpdateCheck.Done(): // When the actual command already finished, we still wait 500ms for the update check to finish case <-time.After(time.Millisecond * 500): log.Debug().Msg("update check stopped due to timeout") cancelWaitForUpdate(errors.New("update check timeout")) } } return nil }