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:
@@ -41,7 +41,8 @@ const stopTimeoutSeconds = 10
|
||||
|
||||
// gitImage is the Docker image used for git operations.
|
||||
// alpine/git v2.47.2 - pulled 2025-12-30
|
||||
const gitImage = "alpine/git@sha256:d86f367afb53d022acc4377741e7334bc20add161bb10234272b91b459b4b7d8"
|
||||
const gitImage = "alpine/git@sha256:" +
|
||||
"d86f367afb53d022acc4377741e7334bc20add161bb10234272b91b459b4b7d8"
|
||||
|
||||
// ErrNotConnected is returned when Docker client is not connected.
|
||||
var ErrNotConnected = errors.New("docker client not connected")
|
||||
@@ -145,7 +146,7 @@ type CreateContainerOptions struct {
|
||||
Volumes []VolumeMount
|
||||
Ports []PortMapping
|
||||
Network string
|
||||
CPULimit float64 // CPU cores (e.g. 0.5 = half a core, 2.0 = two cores). 0 means unlimited.
|
||||
CPULimit float64 // CPU cores (0.5 = half a core). 0 means unlimited.
|
||||
MemoryLimit int64 // Memory in bytes. 0 means unlimited.
|
||||
}
|
||||
|
||||
@@ -303,7 +304,11 @@ func (c *Client) StopContainer(ctx context.Context, containerID ContainerID) err
|
||||
|
||||
timeout := stopTimeoutSeconds
|
||||
|
||||
err := c.docker.ContainerStop(ctx, containerID.String(), container.StopOptions{Timeout: &timeout})
|
||||
err := c.docker.ContainerStop(
|
||||
ctx,
|
||||
containerID.String(),
|
||||
container.StopOptions{Timeout: &timeout},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stop container: %w", err)
|
||||
}
|
||||
@@ -323,7 +328,11 @@ func (c *Client) RemoveContainer(
|
||||
|
||||
c.log.Info("removing container", "id", containerID, "force", force)
|
||||
|
||||
err := c.docker.ContainerRemove(ctx, containerID.String(), container.RemoveOptions{Force: force})
|
||||
err := c.docker.ContainerRemove(
|
||||
ctx,
|
||||
containerID.String(),
|
||||
container.RemoveOptions{Force: force},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove container: %w", err)
|
||||
}
|
||||
@@ -469,7 +478,8 @@ type CloneResult struct {
|
||||
CommitSHA string // The HEAD commit SHA after clone/checkout
|
||||
}
|
||||
|
||||
// CloneRepo clones a git repository using SSH and optionally checks out a specific commit.
|
||||
// CloneRepo clones a git repository using SSH and optionally checks out a
|
||||
// specific commit.
|
||||
// containerDir is the path inside the upaas container (for writing files).
|
||||
// hostDir is the corresponding path on the Docker host (for bind mounts).
|
||||
// If commitSHA is provided, that specific commit will be checked out.
|
||||
@@ -584,11 +594,13 @@ func (c *Client) performBuild(
|
||||
// scannerInitialBufferSize is the initial buffer size for the build log scanner.
|
||||
const scannerInitialBufferSize = 64 * 1024 // 64KB
|
||||
|
||||
// scannerMaxBufferSize is the max buffer size for build log lines (base64 layers can be large).
|
||||
// scannerMaxBufferSize is the max buffer size for build log lines
|
||||
// (base64 layers can be large).
|
||||
const scannerMaxBufferSize = 1024 * 1024 // 1MB
|
||||
|
||||
// streamBuildOutput reads Docker build output line by line and writes to stdout and optional log writer.
|
||||
// Docker sends newline-delimited JSON, so reading line by line ensures each log entry is written immediately.
|
||||
// streamBuildOutput reads Docker build output line by line and writes to
|
||||
// stdout and optional log writer. Docker sends newline-delimited JSON, so
|
||||
// reading line by line ensures each log entry is written immediately.
|
||||
func (c *Client) streamBuildOutput(body io.Reader, logWriter io.Writer) error {
|
||||
scanner := bufio.NewScanner(body)
|
||||
buf := make([]byte, 0, scannerInitialBufferSize)
|
||||
@@ -616,7 +628,10 @@ func (c *Client) streamBuildOutput(body io.Reader, logWriter io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) performClone(ctx context.Context, cfg *cloneConfig) (*CloneResult, error) {
|
||||
func (c *Client) performClone(
|
||||
ctx context.Context,
|
||||
cfg *cloneConfig,
|
||||
) (*CloneResult, error) {
|
||||
// Create work directory for clone destination
|
||||
err := os.MkdirAll(cfg.containerDir, workDirPermissions)
|
||||
if err != nil {
|
||||
@@ -642,7 +657,11 @@ func (c *Client) performClone(ctx context.Context, cfg *cloneConfig) (*CloneResu
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = c.docker.ContainerRemove(ctx, gitContainerID.String(), container.RemoveOptions{Force: true})
|
||||
_ = c.docker.ContainerRemove(
|
||||
ctx,
|
||||
gitContainerID.String(),
|
||||
container.RemoveOptions{Force: true},
|
||||
)
|
||||
}()
|
||||
|
||||
return c.runGitClone(ctx, gitContainerID)
|
||||
@@ -680,7 +699,8 @@ func (c *Client) createGitContainer(
|
||||
entrypoint := []string{}
|
||||
cmd := []string{"sh", "-c", script}
|
||||
|
||||
// Use host paths for Docker bind mounts (Docker runs on the host, not in our container)
|
||||
// Use host paths for Docker bind mounts
|
||||
// (Docker runs on the host, not in our container)
|
||||
resp, err := c.docker.ContainerCreate(ctx,
|
||||
&container.Config{
|
||||
Image: gitImage,
|
||||
@@ -711,13 +731,20 @@ func (c *Client) createGitContainer(
|
||||
return ContainerID(resp.ID), nil
|
||||
}
|
||||
|
||||
func (c *Client) runGitClone(ctx context.Context, containerID ContainerID) (*CloneResult, error) {
|
||||
func (c *Client) runGitClone(
|
||||
ctx context.Context,
|
||||
containerID ContainerID,
|
||||
) (*CloneResult, error) {
|
||||
err := c.docker.ContainerStart(ctx, containerID.String(), container.StartOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to start git container: %w", err)
|
||||
}
|
||||
|
||||
statusCh, errCh := c.docker.ContainerWait(ctx, containerID.String(), container.WaitConditionNotRunning)
|
||||
statusCh, errCh := c.docker.ContainerWait(
|
||||
ctx,
|
||||
containerID.String(),
|
||||
container.WaitConditionNotRunning,
|
||||
)
|
||||
|
||||
select {
|
||||
case err := <-errCh:
|
||||
|
||||
Reference in New Issue
Block a user