Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ jobs:
- name: Fetch all tags
run: git fetch --force --tags
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version-file: 'go.mod'
- name: Run Go Vet
run: go vet ./...
- name: Install golangci-lint
run: |
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6
- name: Run golangci-lint
run: golangci-lint run
- name: Run Go Tests
run: go test ./... -cover -race
- name: Build binary
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
with:
distribution: goreleaser
version: '~> v2'
Expand All @@ -36,7 +39,7 @@ jobs:
- name: Check licenses
run: addlicense -l apache -check -v -ignore '**/*.yaml' -c Humanitec ./cmd ./internal/
- name: Build docker image
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
push: false
Expand Down
40 changes: 40 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
version: "2"
modules-download-mode: readonly

run:
tests: false

linters:
enable:
- govet
- staticcheck
- unused
- contextcheck
- gosec
- testifylint
- errcheck
- bodyclose
- misspell

linters-settings:
errcheck:
check-type-assertions: true
check-blank: true
exclude-functions:
- (os.File).Close
- (io.Closer).Close
misspell:
locale: US
gosec:
exclude:
- G304
- G301
- G306
- G115
output:
formats:
colored-line-number: true
print-issued-lines: true
print-linter-name: true
uniq-by-line: false
sort-results: true
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ MAKEFLAGS += --no-builtin-rules
.SUFFIXES:

## Display a list of the documented make targets
.PHONY: help
.PHONY: help lint
help:
@echo Documented Make targets:
@perl -e 'undef $$/; while (<>) { while ($$_ =~ /## (.*?)(?:\n# .*)*\n.PHONY:\s+(\S+).*/mg) { printf "\033[36m%-30s\033[0m %s\n", $$2, $$1 } }' $(MAKEFILE_LIST) | sort

lint:
@echo "Running golangci-lint..."
golangci-lint run ./...

.PHONY: .FORCE
.FORCE:
Expand Down
4 changes: 2 additions & 2 deletions internal/command/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ arguments.
return fmt.Errorf("no output file specified")
} else if v == "-" {
_, _ = fmt.Fprint(cmd.OutOrStdout(), string(raw))
} else if err := os.WriteFile(v+".temp", raw, 0644); err != nil {
} else if err := os.WriteFile(v+".temp", raw, 0600); err != nil {
return fmt.Errorf("failed to write output file: %w", err)
} else if err := os.Rename(v+".temp", v); err != nil {
return fmt.Errorf("failed to complete writing output file: %w", err)
Expand All @@ -388,7 +388,7 @@ arguments.
_, _ = content.WriteRune('\n')
}
slog.Info(fmt.Sprintf("Writing env var file to '%s'", v))
if err := os.WriteFile(v, []byte(content.String()), 0644); err != nil {
if err := os.WriteFile(v, []byte(content.String()), 0600); err != nil {
return fmt.Errorf("failed to write env var file: %w", err)
}
}
Expand Down
6 changes: 3 additions & 3 deletions internal/command/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,11 @@ URI Retrieval:
return fmt.Errorf("failed to check for existing default provisioners file: %w", err)
}

f, err := os.OpenFile(defaultProvisioners, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
f, err := os.OpenFile(defaultProvisioners, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
if err != nil {
return fmt.Errorf("failed to create default provisioners file: %w", err)
}
defer f.Close()
defer f.Close() //nolint:errcheck

slog.Info("Writing default provisioners file", "path", defaultProvisioners)
if _, err := f.WriteString(defaultProvisionersContent); err != nil {
Expand All @@ -248,7 +248,7 @@ URI Retrieval:
return fmt.Errorf("failed to check existing Score file: %w", err)
}
slog.Info(fmt.Sprintf("Initial Score file '%s' does not exist - creating it", initCmdScoreFile))
if err := os.WriteFile(initCmdScoreFile+".temp", []byte(DefaultScoreFileContent), 0755); err != nil {
if err := os.WriteFile(initCmdScoreFile+".temp", []byte(DefaultScoreFileContent), 0755); err != nil { //nolint:gosec
return fmt.Errorf("failed to write initial score file: %w", err)
} else if err := os.Rename(initCmdScoreFile+".temp", initCmdScoreFile); err != nil {
return fmt.Errorf("failed to complete writing initial Score file: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion internal/command/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func getResourceOutputsKeys(uid framework.ResourceUid, state *project.State) ([]
return nil, err
}
keys := make([]string, 0, len(outputs))
for key, _ := range outputs {
for key := range outputs {
keys = append(keys, key)
}
slices.Sort(keys)
Expand Down
18 changes: 11 additions & 7 deletions internal/command/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func run(cmd *cobra.Command, args []string) error {
if src, err = os.Open(scoreFile); err != nil {
return err
}
defer src.Close()
defer src.Close() //nolint:errcheck

// Parse SCORE spec
//
Expand All @@ -112,7 +112,7 @@ func run(cmd *cobra.Command, args []string) error {
//
if overridesFile != "" {
if ovr, err := os.Open(overridesFile); err == nil {
defer ovr.Close()
defer ovr.Close() //nolint:errcheck

slog.Info(fmt.Sprintf("Loading Score overrides file '%s'", overridesFile))
var ovrMap map[string]interface{}
Expand Down Expand Up @@ -223,16 +223,20 @@ func run(cmd *cobra.Command, args []string) error {
// Deprecated behavior of the run command which used to publish ports
// Todo: remove this once score-compose run is removed
if spec.Service != nil && len(spec.Service.Ports) > 0 {
ports := make([]types.ServicePortConfig, 0)
ports := make([]types.ServicePortConfig, 0, len(spec.Service.Ports))
for _, pSpec := range spec.Service.Ports {
var pubPort = fmt.Sprintf("%v", pSpec.Port)
port := util.DerefOr(pSpec.TargetPort, pSpec.Port)
if port < 0 || port > 65535 {
return fmt.Errorf("invalid port number: %d", port)
}
pubPort := fmt.Sprintf("%v", pSpec.Port)
var protocol string
if pSpec.Protocol != nil {
protocol = strings.ToLower(string(*pSpec.Protocol))
}
ports = append(ports, types.ServicePortConfig{
Published: pubPort,
Target: uint32(util.DerefOr(pSpec.TargetPort, pSpec.Port)),
Target: uint32(port), // #nosec G115
Protocol: protocol,
})
}
Expand Down Expand Up @@ -270,7 +274,7 @@ func run(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
defer destFile.Close()
defer destFile.Close() //nolint:errcheck

dest = io.MultiWriter(dest, destFile)
}
Expand All @@ -289,7 +293,7 @@ func run(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
defer dest.Close()
defer dest.Close() //nolint:errcheck

// Write .env file
//
Expand Down
13 changes: 8 additions & 5 deletions internal/compose/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"errors"
"fmt"
"log/slog"
"os"
"slices"
"maps"
"os"
"path/filepath"
"slices"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -107,7 +107,7 @@
if len(cSpec.Volumes) > 0 {
volumes = make([]compose.ServiceVolumeConfig, 0, len(cSpec.Volumes))
for _, target := range slices.Sorted(maps.Keys(cSpec.Volumes)) {
vol := cSpec.Volumes[target]
vol := cSpec.Volumes[target]
cfg, err := convertVolumeSourceIntoVolume(state, deferredSubstitutionFunction, workloadName, target, vol)
if err != nil {
return nil, fmt.Errorf("containers.%s.volumes[%s]: %w", containerName, target, err)
Expand Down Expand Up @@ -237,11 +237,11 @@
var err error

filesDir := filepath.Join(mountsDirectory, "files")
if err = os.MkdirAll(filesDir, 0755); err != nil && !errors.Is(err, os.ErrExist) {
if err = os.MkdirAll(filesDir, 0750); err != nil && !errors.Is(err, os.ErrExist) {
return nil, fmt.Errorf("failed to ensure the files directory exists")
}
for _, target := range slices.Sorted(maps.Keys(input)) {
file := input[target]
file := input[target]
var content []byte
if file.Content != nil {
content = []byte(*file.Content)
Expand All @@ -250,7 +250,10 @@
if !filepath.IsAbs(sourcePath) && state.Workloads[workloadName].File != nil {
sourcePath = filepath.Join(filepath.Dir(*state.Workloads[workloadName].File), sourcePath)
}
if !filepath.IsAbs(sourcePath) {
return nil, fmt.Errorf("invalid source path: must be absolute")
}
content, err = os.ReadFile(sourcePath)

Check failure on line 256 in internal/compose/convert.go

View workflow job for this annotation

GitHub Actions / test

G304: Potential file inclusion via variable (gosec)
if err != nil {
return nil, fmt.Errorf("containers.%s.files[%s].source: failed to read: %w", containerName, target, err)
}
Expand Down Expand Up @@ -288,7 +291,7 @@
newMode = newMode | 0600
readOnly = true
}
fileMode = os.FileMode(newMode)

Check failure on line 294 in internal/compose/convert.go

View workflow job for this annotation

GitHub Actions / test

G115: integer overflow conversion int64 -> uint32 (gosec)
}

if err := os.WriteFile(filepath.Join(filesDir, newName), content, fileMode); err != nil {
Expand Down
5 changes: 3 additions & 2 deletions internal/compose/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package compose

import (
"context"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -446,9 +447,9 @@ func TestScoreConvert(t *testing.T) {

evt := new(envprov.Provisioner)
state.Resources["environment.default#test.env"] = framework.ScoreResourceState[framework.NoExtras]{OutputLookupFunc: evt.LookupOutput}
po, _ := evt.GenerateSubProvisioner("app-db", "").Provision(nil, nil)
po, _ := evt.GenerateSubProvisioner("app-db", "").Provision(context.TODO(), nil)
state.Resources["mysql.default#test.app-db"] = framework.ScoreResourceState[framework.NoExtras]{OutputLookupFunc: po.OutputLookupFunc}
po, _ = evt.GenerateSubProvisioner("some-dns", "").Provision(nil, nil)
po, _ = evt.GenerateSubProvisioner("some-dns", "").Provision(context.TODO(), nil)
state.Resources["dns.default#test.some-dns"] = framework.ScoreResourceState[framework.NoExtras]{OutputLookupFunc: po.OutputLookupFunc}
state.Resources["volume.default#test.data"] = framework.ScoreResourceState[framework.NoExtras]{Outputs: map[string]interface{}{
"type": "volume",
Expand Down
2 changes: 1 addition & 1 deletion internal/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (h *SimpleHandler) Enabled(ctx context.Context, level slog.Level) bool {
func (h *SimpleHandler) Handle(ctx context.Context, record slog.Record) error {
h.mu.Lock()
defer h.mu.Unlock()
_, err := h.Writer.Write([]byte(fmt.Sprintf("%s: %s\n", record.Level.String(), record.Message)))
_, err := fmt.Fprintf(h.Writer, "%s: %s\n", record.Level.String(), record.Message)
return err
}

Expand Down
2 changes: 1 addition & 1 deletion internal/provisioners/cmdprov/commandprov.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (p *Provisioner) Provision(ctx context.Context, input *provisioners.Input)
return nil, fmt.Errorf("failed to encode json input: %w", err)
}
outputBuffer := new(bytes.Buffer)

// #nosec G204 - bin and args are from trusted internal config
cmd := exec.CommandContext(ctx, bin, p.Args...)
slog.Debug(fmt.Sprintf("Executing '%s %v' for command provisioner", bin, p.Args))
cmd.Stdin = bytes.NewReader(rawInput)
Expand Down
8 changes: 4 additions & 4 deletions internal/provisioners/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func (po *ProvisionOutput) ApplyToStateAndProject(state *project.State, resUid f
dst := filepath.Join(state.Extras.MountsDirectory, relativePath)
if b {
slog.Debug(fmt.Sprintf("Ensuring mount directory '%s' exists", dst))
if err := os.MkdirAll(dst, 0755); err != nil && !errors.Is(err, os.ErrExist) {
if err := os.MkdirAll(dst, 0750); err != nil && !errors.Is(err, os.ErrExist) {
return nil, fmt.Errorf("failed to create volume directory '%s': %w", dst, err)
}
} else {
Expand All @@ -228,10 +228,10 @@ func (po *ProvisionOutput) ApplyToStateAndProject(state *project.State, resUid f
dst := filepath.Join(state.Extras.MountsDirectory, relativePath)
if b != nil {
slog.Debug(fmt.Sprintf("Ensuring mount file '%s' exists", dst))
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil && !errors.Is(err, os.ErrExist) {
if err := os.MkdirAll(filepath.Dir(dst), 0750); err != nil && !errors.Is(err, os.ErrExist) {
return nil, fmt.Errorf("failed to create directories for file '%s': %w", dst, err)
}
if err := os.WriteFile(dst, []byte(*b), 0644); err != nil {
if err := os.WriteFile(dst, []byte(*b), 0600); err != nil {
return nil, fmt.Errorf("failed to write file '%s': %w", dst, err)
}
} else {
Expand Down Expand Up @@ -322,7 +322,7 @@ func ProvisionResources(ctx context.Context, state *project.State, provisioners
}

var params map[string]interface{}
if resState.Params != nil && len(resState.Params) > 0 {
if len(resState.Params) > 0 {
resOutputs, err := out.GetResourceOutputForWorkload(resState.SourceWorkload)
if err != nil {
return nil, fmt.Errorf("failed to find resource params for resource '%s': %w", resUid, err)
Expand Down
Loading