diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e5200473..de856488 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-02-15T11:12:36Z by kres latest. +# Generated on 2024-10-10T13:04:30Z by kres 34e72ac. name: default concurrency: @@ -29,27 +29,44 @@ jobs: - self-hosted - generic if: (!startsWith(github.head_ref, 'renovate/') && !startsWith(github.head_ref, 'dependabot/')) - services: - buildkitd: - image: moby/buildkit:v0.12.5 - options: --privileged - ports: - - 1234:1234 - volumes: - - /var/lib/buildkit/${{ github.repository }}:/var/lib/buildkit - - /usr/etc/buildkit/buildkitd.toml:/etc/buildkit/buildkitd.toml steps: + - name: gather-system-info + id: system-info + uses: kenchan0130/actions-system-info@v1.3.0 + continue-on-error: true + - name: print-system-info + run: | + MEMORY_GB=$((${{ steps.system-info.outputs.totalmem }}/1024/1024/1024)) + + OUTPUTS=( + "CPU Core: ${{ steps.system-info.outputs.cpu-core }}" + "CPU Model: ${{ steps.system-info.outputs.cpu-model }}" + "Hostname: ${{ steps.system-info.outputs.hostname }}" + "NodeName: ${NODE_NAME}" + "Kernel release: ${{ steps.system-info.outputs.kernel-release }}" + "Kernel version: ${{ steps.system-info.outputs.kernel-version }}" + "Name: ${{ steps.system-info.outputs.name }}" + "Platform: ${{ steps.system-info.outputs.platform }}" + "Release: ${{ steps.system-info.outputs.release }}" + "Total memory: ${MEMORY_GB} GB" + ) + + for OUTPUT in "${OUTPUTS[@]}";do + echo "${OUTPUT}" + done + continue-on-error: true - name: checkout uses: actions/checkout@v4 - name: Unshallow run: | git fetch --prune --unshallow - name: Set up Docker Buildx + id: setup-buildx uses: docker/setup-buildx-action@v3 with: driver: remote - endpoint: tcp://localhost:1234 - timeout-minutes: 1 + endpoint: tcp://buildkit-amd64.ci.svc.cluster.local:1234 + timeout-minutes: 10 - name: base run: | make base @@ -60,8 +77,11 @@ jobs: run: | make unit-tests-race - name: coverage - run: | - make coverage + uses: codecov/codecov-action@v4 + with: + files: _out/coverage-unit-tests.txt + token: ${{ secrets.CODECOV_TOKEN }} + timeout-minutes: 3 - name: conform run: | make conform @@ -81,20 +101,23 @@ jobs: - name: push-conform if: github.event_name != 'pull_request' env: + PLATFORM: linux/amd64,linux/arm64 PUSH: "true" run: | make image-conform - name: push-conform-latest - if: github.event_name != 'pull_request' + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' env: + PLATFORM: linux/amd64,linux/arm64 PUSH: "true" run: | - make image-conform TAG=latest + make image-conform IMAGE_TAG=latest - name: Generate Checksums if: startsWith(github.ref, 'refs/tags/') run: | - sha256sum _out/conform-* > _out/sha256sum.txt - sha512sum _out/conform-* > _out/sha512sum.txt + cd _out + sha256sum conform-* > sha256sum.txt + sha512sum conform-* > sha512sum.txt - name: release-notes if: startsWith(github.ref, 'refs/tags/') run: | diff --git a/.golangci.yml b/.golangci.yml index c9e23c5f..945691f6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,21 +1,20 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-02-15T11:12:36Z by kres latest. +# Generated on 2024-10-10T13:02:45Z by kres 34e72ac. # options for analysis running run: timeout: 10m issues-exit-code: 1 tests: true - build-tags: [] - skip-dirs: [] - skip-dirs-use-default: true - skip-files: [] + build-tags: [ ] modules-download-mode: readonly # output configuration options output: - format: colored-line-number + formats: + - format: colored-line-number + path: stdout print-issued-lines: true print-linter-name: true uniq-by-line: true @@ -32,54 +31,35 @@ linters-settings: check-blank: true exhaustive: default-signifies-exhaustive: false - funlen: - lines: 60 - statements: 40 gci: - local-prefixes: github.com/siderolabs/conform/ + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + - localmodule # Imports from the same module. gocognit: min-complexity: 30 - ireturn: - allow: - - anon - - error - - empty - - stdlib - - github.com\/talos-systems\/kres\/internal\/dag.Node nestif: min-complexity: 5 goconst: min-len: 3 min-occurrences: 3 gocritic: - disabled-checks: [] + disabled-checks: [ ] gocyclo: min-complexity: 20 godot: - check-all: false - godox: - keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting - - NOTE - - OPTIMIZE # marks code that should be optimized before merging - - HACK # marks hack-arounds that should be removed before merging + scope: declarations gofmt: simplify: true - goimports: - local-prefixes: github.com/siderolabs/conform/ - golint: - min-confidence: 0.8 - gomnd: - settings: {} - gomodguard: {} + gomodguard: { } govet: - check-shadowing: true enable-all: true lll: line-length: 200 tab-width: 4 misspell: locale: US - ignore-words: [] + ignore-words: [ ] nakedret: max-func-lines: 30 prealloc: @@ -88,16 +68,15 @@ linters-settings: for-loops: false # Report preallocation suggestions on for loops, false by default nolintlint: allow-unused: false - allow-leading-space: false - allow-no-explanation: [] + allow-no-explanation: [ ] require-explanation: false require-specific: true - rowserrcheck: {} - testpackage: {} + rowserrcheck: { } + testpackage: { } unparam: check-exported: false unused: - check-exported: false + local-variables-are-used: false whitespace: multi-if: false # Enforces newlines (or comments) after every multi-line if statement multi-func: false # Enforces newlines (or comments) after every multi-line function signature @@ -113,12 +92,17 @@ linters-settings: gofumpt: extra-rules: false cyclop: - # the maximal code complexity to report - max-complexity: 20 - # depguard: - # Main: - # deny: - # - github.com/OpenPeeDeeP/depguard # this is just an example + # the maximal code complexity to report + max-complexity: 20 + depguard: + rules: + prevent_unmaintained_packages: + list-mode: lax # allow unless explicitly denied + files: + - $all + deny: + - pkg: io/ioutil + desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil" linters: enable-all: true @@ -126,47 +110,35 @@ linters: fast: false disable: - exhaustruct - - exhaustivestruct + - err113 - forbidigo - funlen - - gas - gochecknoglobals - gochecknoinits - godox - - goerr113 - gomnd - gomoddirectives + - gosec + - inamedparam - ireturn + - mnd - nestif - nonamedreturns - - nosnakecase - paralleltest + - tagalign - tagliatelle - thelper - - typecheck - varnamelen - wrapcheck - - depguard # Disabled because starting with golangci-lint 1.53.0 it doesn't allow denylist alone anymore - - tagalign - - inamedparam - testifylint # complains about our assert recorder and has a number of false positives for assert.Greater(t, thing, 1) - protogetter # complains about us using Value field on typed spec, instead of GetValue which has a different signature - perfsprint # complains about us using fmt.Sprintf in non-performance critical code, updating just kres took too long - # abandoned linters for which golangci shows the warning that the repo is archived by the owner - - interfacer - - maligned - - golint - - scopelint - - varcheck - - deadcode - - structcheck - - ifshort - # disabled as it seems to be broken - goes into imported libraries and reports issues there - - musttag + - goimports # same as gci + - musttag # seems to be broken - goes into imported libraries and reports issues there issues: - exclude: [] - exclude-rules: [] + exclude: [ ] + exclude-rules: [ ] exclude-use-default: false exclude-case-sensitive: false max-issues-per-linter: 10 diff --git a/.kres.yaml b/.kres.yaml index e056450c..036afc03 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -1,3 +1,10 @@ +--- +kind: common.Image +name: image-conform +spec: + extraEnvironment: + PLATFORM: linux/amd64,linux/arm64 +--- kind: golang.Build spec: outputs: diff --git a/Dockerfile b/Dockerfile index 2b3800f1..9cb68d29 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,39 +1,38 @@ -# syntax = docker/dockerfile-upstream:1.6.0-labs +# syntax = docker/dockerfile-upstream:1.10.0-labs # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-03-01T05:36:30Z by kres latest. +# Generated on 2024-10-10T13:02:45Z by kres 34e72ac. ARG TOOLCHAIN -FROM ghcr.io/siderolabs/ca-certificates:v1.6.0 AS image-ca-certificates +FROM ghcr.io/siderolabs/ca-certificates:v1.8.0 AS image-ca-certificates -FROM ghcr.io/siderolabs/fhs:v1.6.0 AS image-fhs +FROM ghcr.io/siderolabs/fhs:v1.8.0 AS image-fhs # runs markdownlint -FROM docker.io/node:21.6.2-alpine3.19 AS lint-markdown +FROM docker.io/oven/bun:1.1.29-alpine AS lint-markdown WORKDIR /src -RUN npm i -g markdownlint-cli@0.39.0 -RUN npm i sentences-per-line@0.2.1 +RUN bun i markdownlint-cli@0.41.0 sentences-per-line@0.2.1 COPY .markdownlint.json . COPY ./CHANGELOG.md ./CHANGELOG.md COPY ./README.md ./README.md -RUN markdownlint --ignore "CHANGELOG.md" --ignore "**/node_modules/**" --ignore '**/hack/chglog/**' --rules node_modules/sentences-per-line/index.js . +RUN bunx markdownlint --ignore "CHANGELOG.md" --ignore "**/node_modules/**" --ignore '**/hack/chglog/**' --rules node_modules/sentences-per-line/index.js . # base toolchain image -FROM ${TOOLCHAIN} AS toolchain +FROM --platform=${BUILDPLATFORM} ${TOOLCHAIN} AS toolchain RUN apk --update --no-cache add bash curl build-base protoc protobuf-dev git # build tools FROM --platform=${BUILDPLATFORM} toolchain AS tools -ENV GO111MODULE on +ENV GO111MODULE=on ARG CGO_ENABLED -ENV CGO_ENABLED ${CGO_ENABLED} +ENV CGO_ENABLED=${CGO_ENABLED} ARG GOTOOLCHAIN -ENV GOTOOLCHAIN ${GOTOOLCHAIN} +ENV GOTOOLCHAIN=${GOTOOLCHAIN} ARG GOEXPERIMENT -ENV GOEXPERIMENT ${GOEXPERIMENT} -ENV GOPATH /go +ENV GOEXPERIMENT=${GOEXPERIMENT} +ENV GOPATH=/go ARG DEEPCOPY_VERSION RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install github.com/siderolabs/deep-copy@${DEEPCOPY_VERSION} \ && mv /go/bin/deep-copy /bin/deep-copy @@ -42,9 +41,6 @@ RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/g && mv /go/bin/golangci-lint /bin/golangci-lint RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install golang.org/x/vuln/cmd/govulncheck@latest \ && mv /go/bin/govulncheck /bin/govulncheck -ARG GOIMPORTS_VERSION -RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION} \ - && mv /go/bin/goimports /bin/goimports ARG GOFUMPT_VERSION RUN go install mvdan.cc/gofumpt@${GOFUMPT_VERSION} \ && mv /go/bin/gofumpt /bin/gofumpt @@ -73,15 +69,12 @@ RUN mkdir -p internal/version/data && \ FROM base AS lint-gofumpt RUN FILES="$(gofumpt -l .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'gofumpt -w .':\n${FILES}"; exit 1) -# runs goimports -FROM base AS lint-goimports -RUN FILES="$(goimports -l -local github.com/siderolabs/conform/ .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'goimports -w -local github.com/siderolabs/conform/ .':\n${FILES}"; exit 1) - # runs golangci-lint FROM base AS lint-golangci-lint WORKDIR /src COPY .golangci.yml . -ENV GOGC 50 +ENV GOGC=50 +RUN golangci-lint config verify --config .golangci.yml RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/root/.cache/golangci-lint --mount=type=cache,target=/go/pkg golangci-lint run --config .golangci.yml # runs govulncheck @@ -187,6 +180,6 @@ ARG TARGETARCH COPY --from=conform conform-linux-${TARGETARCH} /conform COPY --from=image-fhs / / COPY --from=image-ca-certificates / / -LABEL org.opencontainers.image.source https://github.com/siderolabs/conform +LABEL org.opencontainers.image.source=https://github.com/siderolabs/conform ENTRYPOINT ["/conform"] diff --git a/Makefile b/Makefile index 88ff9083..eded0e37 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,31 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-03-01T05:36:30Z by kres latest. +# Generated on 2024-10-10T13:02:45Z by kres 34e72ac. # common variables SHA := $(shell git describe --match=none --always --abbrev=8 --dirty) -TAG := $(shell git describe --tag --always --dirty) +TAG := $(shell git describe --tag --always --dirty --match v[0-9]\*) ABBREV_TAG := $(shell git describe --tags >/dev/null 2>/dev/null && git describe --tag --always --match v[0-9]\* --abbrev=0 || echo 'undefined') BRANCH := $(shell git rev-parse --abbrev-ref HEAD) ARTIFACTS := _out +IMAGE_TAG ?= $(TAG) +OPERATING_SYSTEM := $(shell uname -s | tr '[:upper:]' '[:lower:]') +GOARCH := $(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') WITH_DEBUG ?= false WITH_RACE ?= false REGISTRY ?= ghcr.io USERNAME ?= siderolabs REGISTRY_AND_USERNAME ?= $(REGISTRY)/$(USERNAME) -PROTOBUF_GO_VERSION ?= 1.32.0 -GRPC_GO_VERSION ?= 1.3.0 -GRPC_GATEWAY_VERSION ?= 2.19.1 +PROTOBUF_GO_VERSION ?= 1.34.2 +GRPC_GO_VERSION ?= 1.5.1 +GRPC_GATEWAY_VERSION ?= 2.22.0 VTPROTOBUF_VERSION ?= 0.6.0 +GOIMPORTS_VERSION ?= 0.25.0 DEEPCOPY_VERSION ?= v0.5.6 -GOLANGCILINT_VERSION ?= v1.56.2 -GOFUMPT_VERSION ?= v0.6.0 -GO_VERSION ?= 1.22.0 -GOIMPORTS_VERSION ?= v0.18.0 +GOLANGCILINT_VERSION ?= v1.61.0 +GOFUMPT_VERSION ?= v0.7.0 +GO_VERSION ?= 1.23.2 GO_BUILDFLAGS ?= GO_LDFLAGS ?= CGO_ENABLED ?= 0 @@ -59,12 +62,12 @@ COMMON_ARGS += --build-arg=PROTOBUF_GO_VERSION="$(PROTOBUF_GO_VERSION)" COMMON_ARGS += --build-arg=GRPC_GO_VERSION="$(GRPC_GO_VERSION)" COMMON_ARGS += --build-arg=GRPC_GATEWAY_VERSION="$(GRPC_GATEWAY_VERSION)" COMMON_ARGS += --build-arg=VTPROTOBUF_VERSION="$(VTPROTOBUF_VERSION)" +COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" COMMON_ARGS += --build-arg=DEEPCOPY_VERSION="$(DEEPCOPY_VERSION)" COMMON_ARGS += --build-arg=GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" -COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" COMMON_ARGS += --build-arg=GOFUMPT_VERSION="$(GOFUMPT_VERSION)" COMMON_ARGS += --build-arg=TESTPKGS="$(TESTPKGS)" -TOOLCHAIN ?= docker.io/golang:1.22-alpine +TOOLCHAIN ?= docker.io/golang:1.23-alpine # help menu @@ -110,7 +113,7 @@ If you already have a compatible builder instance, you may use that instead. ## Artifacts All artifacts will be output to ./$(ARTIFACTS). Images will be tagged with the -registry "$(REGISTRY)", username "$(USERNAME)", and a dynamic tag (e.g. $(IMAGE):$(TAG)). +registry "$(REGISTRY)", username "$(USERNAME)", and a dynamic tag (e.g. $(IMAGE):$(IMAGE_TAG)). The registry and username can be overridden by exporting REGISTRY, and USERNAME respectively. @@ -130,6 +133,9 @@ endif all: unit-tests conform image-conform lint +$(ARTIFACTS): ## Creates artifacts directory. + @mkdir -p $(ARTIFACTS) + .PHONY: clean clean: ## Cleans up all artifacts. @rm -rf $(ARTIFACTS) @@ -160,9 +166,6 @@ fmt: ## Formats the source code lint-govulncheck: ## Runs govulncheck linter. @$(MAKE) target-$@ -lint-goimports: ## Runs goimports linter. - @$(MAKE) target-$@ - .PHONY: base base: ## Prepare base toolchain @$(MAKE) target-$@ @@ -175,10 +178,6 @@ unit-tests: ## Performs unit tests unit-tests-race: ## Performs unit tests with race detection enabled. @$(MAKE) target-$@ -.PHONY: coverage -coverage: ## Upload coverage data to codecov.io. - bash -c "bash <(curl -s https://codecov.io/bash) -f $(ARTIFACTS)/coverage-unit-tests.txt -X fix" - .PHONY: $(ARTIFACTS)/conform-darwin-amd64 $(ARTIFACTS)/conform-darwin-amd64: @$(MAKE) local-conform-darwin-amd64 DEST=$(ARTIFACTS) @@ -215,11 +214,11 @@ lint-markdown: ## Runs markdownlint. @$(MAKE) target-$@ .PHONY: lint -lint: lint-golangci-lint lint-gofumpt lint-govulncheck lint-goimports lint-markdown ## Run all linters for the project. +lint: lint-golangci-lint lint-gofumpt lint-govulncheck lint-markdown ## Run all linters for the project. .PHONY: image-conform image-conform: ## Builds image for conform. - @$(MAKE) target-$@ TARGET_ARGS="--tag=$(REGISTRY)/$(USERNAME)/conform:$(TAG)" + @$(MAKE) target-$@ TARGET_ARGS="--tag=$(REGISTRY)/$(USERNAME)/conform:$(IMAGE_TAG)" .PHONY: rekres rekres: @@ -232,8 +231,7 @@ help: ## This help menu. @grep -E '^[a-zA-Z%_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' .PHONY: release-notes -release-notes: - mkdir -p $(ARTIFACTS) +release-notes: $(ARTIFACTS) @ARTIFACTS=$(ARTIFACTS) ./hack/release.sh $@ $(ARTIFACTS)/RELEASE_NOTES.md $(TAG) .PHONY: conformance diff --git a/hack/release.sh b/hack/release.sh index 48d44b28..224323d7 100755 --- a/hack/release.sh +++ b/hack/release.sh @@ -1,8 +1,8 @@ -#!/bin/bash +#!/usr/bin/env bash # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2022-03-23T18:24:36Z by kres latest. +# Generated on 2024-10-10T13:02:45Z by kres 34e72ac. set -e @@ -44,9 +44,92 @@ function commit { exit 1 fi + if is_on_main_branch; then + update_license_files + fi + git commit -s -m "release($1): prepare release" -m "This is the official $1 release." } +function is_on_main_branch { + main_remotes=("upstream" "origin") + branch_names=("main" "master") + current_branch=$(git rev-parse --abbrev-ref HEAD) + + echo "Check current branch: $current_branch" + + for remote in "${main_remotes[@]}"; do + echo "Fetch remote $remote..." + + if ! git fetch --quiet "$remote" &>/dev/null; then + echo "Failed to fetch $remote, skip..." + + continue + fi + + for branch_name in "${branch_names[@]}"; do + if ! git rev-parse --verify "$branch_name" &>/dev/null; then + echo "Branch $branch_name does not exist, skip..." + + continue + fi + + echo "Branch $remote/$branch_name exists, comparing..." + + merge_base=$(git merge-base "$current_branch" "$remote/$branch_name") + latest_main=$(git rev-parse "$remote/$branch_name") + + if [ "$merge_base" = "$latest_main" ]; then + echo "Current branch is up-to-date with $remote/$branch_name" + + return 0 + else + echo "Current branch is not on $remote/$branch_name" + + return 1 + fi + done + done + + echo "No main or master branch found on any remote" + + return 1 +} + +function update_license_files { + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + parent_dir="$(dirname "$script_dir")" + current_year=$(date +"%Y") + change_date=$(date -v+4y +"%Y-%m-%d" 2>/dev/null || date -d "+4 years" +"%Y-%m-%d" 2>/dev/null || date --date="+4 years" +"%Y-%m-%d") + + # Find LICENSE and .kres.yaml files recursively in the parent directory (project root) + find "$parent_dir" \( -name "LICENSE" -o -name ".kres.yaml" \) -type f | while read -r file; do + temp_file="${file}.tmp" + + if [[ $file == *"LICENSE" ]]; then + if grep -q "^Business Source License" "$file"; then + sed -e "s/The Licensed Work is (c) [0-9]\{4\}/The Licensed Work is (c) $current_year/" \ + -e "s/Change Date: [0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/Change Date: $change_date/" \ + "$file" >"$temp_file" + else + continue # Not a Business Source License file + fi + elif [[ $file == *".kres.yaml" ]]; then + sed -E 's/^([[:space:]]*)ChangeDate:.*$/\1ChangeDate: "'"$change_date"'"/' "$file" >"$temp_file" + fi + + # Check if the file has changed + if ! cmp -s "$file" "$temp_file"; then + mv "$temp_file" "$file" + echo "Updated: $file" + git add "$file" + else + echo "No changes: $file" + rm "$temp_file" + fi + done +} + if declare -f "$1" > /dev/null then cmd="$1" @@ -55,7 +138,7 @@ then else cat <