Update golangci-lint to v2.12.2 with canonical config
All checks were successful
Check / check (pull_request) Successful in 3m22s
All checks were successful
Check / check (pull_request) Successful in 3m22s
Bump golangci-lint from v2.10.1 to v2.12.2 in the Dockerfile lint stage (tag+digest pin) and script/bootstrap release-archive pins (linux amd64/arm64 sha256s). Replace .golangci.yml with the canonical v2-layout config so linter settings (lll 88, funlen 80/50, cyclop 15, dupl 100) actually apply. Fix all findings surfaced by the new linter and config: - noctx: use httptest.NewRequestWithContext in all tests - gosec G710/G703: route app redirects through a path-escaping redirectToApp helper; annotate internal log path usage - goconst: introduce shared constants for template/JSON keys and repeated test literals - lll: wrap lines to the 88-column limit - dupl: extract shared helpers (generic findAllByAppID in models, deleteAppResource in handlers, parsePush in webhook payloads, table-driven/helper-based test dedup) - nolintlint: drop nolint directives made obsolete by the new limits Record the change in TODO.md; make check is green.
This commit is contained in:
@@ -66,7 +66,8 @@ const logFilePermissions = 0o640
|
||||
// logTimestampFormat is the format for log file timestamps.
|
||||
const logTimestampFormat = "20060102T150405Z"
|
||||
|
||||
// logFileShortSHALength is the number of characters to use for commit SHA in log filenames.
|
||||
// logFileShortSHALength is the number of characters to use for commit SHA
|
||||
// in log filenames.
|
||||
const logFileShortSHALength = 12
|
||||
|
||||
// dockerLogMessage represents a Docker build log message.
|
||||
@@ -87,7 +88,10 @@ type deploymentLogWriter struct {
|
||||
flushCtx context.Context //nolint:containedctx // needed for async flush goroutine
|
||||
}
|
||||
|
||||
func newDeploymentLogWriter(ctx context.Context, deployment *models.Deployment) *deploymentLogWriter {
|
||||
func newDeploymentLogWriter(
|
||||
ctx context.Context,
|
||||
deployment *models.Deployment,
|
||||
) *deploymentLogWriter {
|
||||
w := &deploymentLogWriter{
|
||||
deployment: deployment,
|
||||
done: make(chan struct{}),
|
||||
@@ -257,7 +261,10 @@ func (svc *Service) GetBuildDir(appName string) string {
|
||||
|
||||
// GetLogFilePath returns the path to the log file for a deployment.
|
||||
// Returns empty string if the path cannot be determined.
|
||||
func (svc *Service) GetLogFilePath(app *models.App, deployment *models.Deployment) string {
|
||||
func (svc *Service) GetLogFilePath(
|
||||
app *models.App,
|
||||
deployment *models.Deployment,
|
||||
) string {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
hostname = "unknown"
|
||||
@@ -275,7 +282,8 @@ func (svc *Service) GetLogFilePath(app *models.App, deployment *models.Deploymen
|
||||
// Use started_at timestamp
|
||||
timestamp := deployment.StartedAt.UTC().Format(logTimestampFormat)
|
||||
|
||||
// Build filename: appname_sha_timestamp.log.txt (or appname_timestamp.log.txt if no SHA)
|
||||
// Build filename: appname_sha_timestamp.log.txt
|
||||
// (or appname_timestamp.log.txt if no SHA)
|
||||
var filename string
|
||||
if sha != "" {
|
||||
filename = fmt.Sprintf("%s_%s_%s.log.txt", app.Name, sha, timestamp)
|
||||
@@ -308,7 +316,8 @@ func (svc *Service) CancelDeploy(appID string) bool {
|
||||
|
||||
// Deploy deploys an app. If cancelExisting is true (e.g. webhook-triggered),
|
||||
// any in-progress deploy for the same app will be cancelled before starting.
|
||||
// If cancelExisting is false and a deploy is in progress, ErrDeploymentInProgress is returned.
|
||||
// If cancelExisting is false and a deploy is in progress,
|
||||
// ErrDeploymentInProgress is returned.
|
||||
func (svc *Service) Deploy(
|
||||
ctx context.Context,
|
||||
app *models.App,
|
||||
@@ -342,7 +351,8 @@ func (svc *Service) Deploy(
|
||||
// Fetch webhook event and create deployment record
|
||||
webhookEvent := svc.fetchWebhookEvent(deployCtx, webhookEventID)
|
||||
|
||||
// Use a background context for DB operations that must complete regardless of cancellation
|
||||
// Use a background context for DB operations that must complete
|
||||
// regardless of cancellation
|
||||
bgCtx := context.WithoutCancel(deployCtx)
|
||||
|
||||
deployment, err := svc.createDeploymentRecord(bgCtx, app, webhookEventID, webhookEvent)
|
||||
@@ -401,7 +411,10 @@ func (svc *Service) createRollbackDeployment(
|
||||
return nil, fmt.Errorf("failed to create rollback deployment: %w", saveErr)
|
||||
}
|
||||
|
||||
_ = deployment.AppendLog(ctx, "Rolling back to previous image: "+app.PreviousImageID.String)
|
||||
_ = deployment.AppendLog(
|
||||
ctx,
|
||||
"Rolling back to previous image: "+app.PreviousImageID.String,
|
||||
)
|
||||
|
||||
return deployment, nil
|
||||
}
|
||||
@@ -417,7 +430,11 @@ func (svc *Service) executeRollback(
|
||||
|
||||
svc.removeOldContainer(ctx, app, deployment)
|
||||
|
||||
rollbackOpts, err := svc.buildContainerOptions(ctx, app, docker.ImageID(previousImageID))
|
||||
rollbackOpts, err := svc.buildContainerOptions(
|
||||
ctx,
|
||||
app,
|
||||
docker.ImageID(previousImageID),
|
||||
)
|
||||
if err != nil {
|
||||
svc.failDeployment(bgCtx, app, deployment, err)
|
||||
|
||||
@@ -426,7 +443,12 @@ func (svc *Service) executeRollback(
|
||||
|
||||
containerID, err := svc.docker.CreateContainer(ctx, rollbackOpts)
|
||||
if err != nil {
|
||||
svc.failDeployment(bgCtx, app, deployment, fmt.Errorf("failed to create rollback container: %w", err))
|
||||
svc.failDeployment(
|
||||
bgCtx,
|
||||
app,
|
||||
deployment,
|
||||
fmt.Errorf("failed to create rollback container: %w", err),
|
||||
)
|
||||
|
||||
return fmt.Errorf("failed to create rollback container: %w", err)
|
||||
}
|
||||
@@ -436,7 +458,12 @@ func (svc *Service) executeRollback(
|
||||
|
||||
startErr := svc.docker.StartContainer(ctx, containerID)
|
||||
if startErr != nil {
|
||||
svc.failDeployment(bgCtx, app, deployment, fmt.Errorf("failed to start rollback container: %w", startErr))
|
||||
svc.failDeployment(
|
||||
bgCtx,
|
||||
app,
|
||||
deployment,
|
||||
fmt.Errorf("failed to start rollback container: %w", startErr),
|
||||
)
|
||||
|
||||
return fmt.Errorf("failed to start rollback container: %w", startErr)
|
||||
}
|
||||
@@ -695,7 +722,11 @@ func (svc *Service) cleanupCancelledDeploy(
|
||||
if removeErr != nil {
|
||||
svc.log.Error("failed to remove image from cancelled deploy",
|
||||
"error", removeErr, "app", app.Name, "image", imageID)
|
||||
_ = deployment.AppendLog(ctx, "WARNING: failed to clean up image "+imageID.String()+": "+removeErr.Error())
|
||||
_ = deployment.AppendLog(
|
||||
ctx,
|
||||
"WARNING: failed to clean up image "+
|
||||
imageID.String()+": "+removeErr.Error(),
|
||||
)
|
||||
} else {
|
||||
svc.log.Info("cleaned up image from cancelled deploy",
|
||||
"app", app.Name, "image", imageID)
|
||||
@@ -870,14 +901,24 @@ func (svc *Service) cloneRepository(
|
||||
|
||||
err := os.MkdirAll(appBuildsDir, buildsDirPermissions)
|
||||
if err != nil {
|
||||
svc.failDeployment(ctx, app, deployment, fmt.Errorf("failed to create builds dir: %w", err))
|
||||
svc.failDeployment(
|
||||
ctx,
|
||||
app,
|
||||
deployment,
|
||||
fmt.Errorf("failed to create builds dir: %w", err),
|
||||
)
|
||||
|
||||
return "", nil, fmt.Errorf("failed to create builds dir: %w", err)
|
||||
}
|
||||
|
||||
buildDir, err := os.MkdirTemp(appBuildsDir, fmt.Sprintf("%d-*", deployment.ID))
|
||||
if err != nil {
|
||||
svc.failDeployment(ctx, app, deployment, fmt.Errorf("failed to create temp dir: %w", err))
|
||||
svc.failDeployment(
|
||||
ctx,
|
||||
app,
|
||||
deployment,
|
||||
fmt.Errorf("failed to create temp dir: %w", err),
|
||||
)
|
||||
|
||||
return "", nil, fmt.Errorf("failed to create temp dir: %w", err)
|
||||
}
|
||||
@@ -908,7 +949,12 @@ func (svc *Service) cloneRepository(
|
||||
)
|
||||
if cloneErr != nil {
|
||||
cleanup()
|
||||
svc.failDeployment(ctx, app, deployment, fmt.Errorf("failed to clone repo: %w", cloneErr))
|
||||
svc.failDeployment(
|
||||
ctx,
|
||||
app,
|
||||
deployment,
|
||||
fmt.Errorf("failed to clone repo: %w", cloneErr),
|
||||
)
|
||||
|
||||
return "", nil, fmt.Errorf("failed to clone repo: %w", cloneErr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user