diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..aca914d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,56 @@ +# Copyright (c) Abstract Machines +# SPDX-License-Identifier: Apache-2.0 + +name: Create and publish a Docker image + +on: + push: + branches: ["main"] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Check for changes in services + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + certs: + - "certs/**" + - "cmd/certs/**" + - "docker/Dockerfile" + + dependencies: + - "go.mod" + - "go.sum" + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build certs and push Docker image + if: steps.filter.outputs.certs == 'true' || steps.filter.outputs.dependencies == 'true' + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + build-args: | + SVC=certs + tags: ghcr.io/absmach/certs:latest diff --git a/.github/workflows/check-generated-files.yml b/.github/workflows/check-generated-files.yml new file mode 100644 index 0000000..10c7d3a --- /dev/null +++ b/.github/workflows/check-generated-files.yml @@ -0,0 +1,115 @@ +# Copyright (c) Abstract Machines +# SPDX-License-Identifier: Apache-2.0 + +name: Check the consistency of generated files + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + check-generated-files: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.23.x + cache-dependency-path: "go.sum" + + - name: Check for changes in go.mod + run: | + go mod tidy + git diff --exit-code + + - name: Check for changes in specific paths + uses: dorny/paths-filter@v3 + id: changes + with: + base: main + filters: | + proto: + - ".github/workflows/check-generated-files.yml" + + mocks: + - ".github/workflows/check-generated-files.yml" + - "sdk/mocks/sdk.go" + - "mocks/repository.go" + - "mocks/service.go" + + - name: Set up protoc + if: steps.changes.outputs.proto == 'true' + run: | + PROTOC_VERSION=27.2 + PROTOC_GEN_VERSION=v1.34.2 + PROTOC_GRPC_VERSION=v1.4.0 + + # Download and install protoc + PROTOC_ZIP=protoc-$PROTOC_VERSION-linux-x86_64.zip + curl -0L -o $PROTOC_ZIP https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/$PROTOC_ZIP + unzip -o $PROTOC_ZIP -d protoc3 + sudo mv protoc3/bin/* /usr/local/bin/ + sudo mv protoc3/include/* /usr/local/include/ + rm -rf $PROTOC_ZIP protoc3 + + # Install protoc-gen-go and protoc-gen-go-grpc + go install google.golang.org/protobuf/cmd/protoc-gen-go@$PROTOC_GEN_VERSION + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@$PROTOC_GRPC_VERSION + + # Add protoc to the PATH + export PATH=$PATH:/usr/local/bin/protoc + + - name: Check Protobuf is up to Date + if: steps.changes.outputs.proto == 'true' + run: | + for p in $(find . -name "*.pb.go"); do + mv $p $p.tmp + done + + make proto + + for p in $(find . -name "*.pb.go"); do + if ! cmp -s $p $p.tmp; then + echo "Error: Proto file and generated Go file $p are out of sync!" + echo "Please run 'make proto' with protoc version $PROTOC_VERSION, protoc-gen-go version $PROTOC_GEN_VERSION and protoc-gen-go-grpc version $PROTOC_GRPC_VERSION and commit the changes." + exit 1 + fi + done + + - name: Check Mocks are up to Date + if: steps.changes.outputs.mocks == 'true' + run: | + MOCKERY_VERSION=v2.43.2 + STRINGER_VERSION=v0.19.0 + + go install github.com/vektra/mockery/v2@$MOCKERY_VERSION + go install golang.org/x/tools/cmd/stringer@$STRINGER_VERSION + + mv ./sdk/mocks/sdk.go ./sdk/mocks/sdk.go.tmp + mv ./mocks/repository.go ./mocks/repository.go.tmp + mv ./mocks/service.go ./mocks/service.go.tmp + + make mocks + + check_mock_changes() { + local file_path=$1 + local tmp_file_path=$1.tmp + local entity_name=$2 + + if ! cmp -s "$file_path" "$tmp_file_path"; then + echo "Error: Generated mocks for $entity_name are out of sync!" + echo "Please run 'make mocks' with mockery version $MOCKERY_VERSION and commit the changes." + exit 1 + fi + } + + check_mock_changes ./sdk/mocks/sdk.go "SDK ./sdk/mocks/sdk.go" + check_mock_changes ./mocks/repository.go "Certs Repository ./mocks/repository.go" + check_mock_changes ./mocks/service.go "Certs Service ./mocks/service.go" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e1f74b7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,112 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + lint-and-build: + name: Lint and Build + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.22.x + cache-dependency-path: "go.sum" + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.60.3 + args: --config ./.golangci.yml + + - name: Build all Binaries + run: make all + + run-test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: 1.23.x + + - name: Install dependencies + uses: actions/setup-node@v4 + with: + node-version: lts/* + + - name: Install dependencies + run: npm install + + - name: Run Prettier + id: prettier-run + uses: rutajdash/prettier-cli-action@v1.0.1 + with: + config_path: ./.prettierrc + file_pattern: "**/*.html **/*.css" + + - name: Prettier Output + if: ${{ failure() }} + shell: bash + run: | + echo "The following files are not formatted:" + echo "${{steps.prettier-run.outputs.prettier_output}}" + + - name: Check for changes in services + uses: dorny/paths-filter@v3 + id: filter + with: + base: main + filters: | + workflow: + - ".github/workflows/ci.yaml" + + certs: + - "cmd/certs/**" + - "sdk/**" + - "certs.pb.go" + - "certs_grpc.pb.go" + - "postgres/**" + + cli: + - "cmd/cli/**" + - "sdk/**" + - "cli/**" + + - name: Create coverage directory + run: mkdir coverage + + - name: Run certs tests + if: steps.changes.outputs.certs == 'true' || steps.changes.outputs.workflow == 'true' + run: go test --race -v -count=1 -coverprofile=coverage/certs.out ./... + + - name: Run cli tests + if: steps.changes.outputs.cli == 'true' || steps.changes.outputs.workflow == 'true' + run: go test --race -v -count=1 -coverprofile=coverage/cli.out ./cli/... + + - name: Run postgres tests + if: steps.changes.outputs.postgres == 'true' || steps.changes.outputs.workflow == 'true' + run: go test --race -v -count=1 -coverprofile=coverage/postgres.out ./postgres/... + + - name: Run sdk tests + if: steps.changes.outputs.sdk == 'true' || steps.changes.outputs.workflow == 'true' + run: go test --race -v -count=1 -coverprofile=coverage/sdk.out ./sdk/... + + - name: Upload coverage + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV }} + directory: ./coverage/ + name: codecov-umbrella + verbose: true diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..23f08b9 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,81 @@ +# Copyright (c) Abstract Machines +# SPDX-License-Identifier: Apache-2.0 + +run: + timeout: 10m + +issues: + max-issues-per-linter: 100 + max-same-issues: 100 + exclude: + - "string `Usage:\n` has (\\d+) occurrences, make it a constant" + - "string `For example:\n` has (\\d+) occurrences, make it a constant" + +linters-settings: + importas: + no-unaliased: true + no-extra-aliases: false + + gocritic: + enabled-checks: + - importShadow + - httpNoBody + - paramTypeCombine + - emptyStringTest + - builtinShadow + - exposedSyncMutex + disabled-checks: + - appendAssign + enabled-tags: + - diagnostic + disabled-tags: + - performance + - style + - experimental + - opinionated + + stylecheck: + checks: ["-ST1000", "-ST1003", "-ST1020", "-ST1021", "-ST1022"] + goheader: + template: |- + Copyright (c) Abstract Machines + SPDX-License-Identifier: Apache-2.0 + +linters: + disable-all: true + enable: + - gocritic + - gosimple + - errcheck + - unused + - goconst + - godot + - godox + - ineffassign + - misspell + - stylecheck + - whitespace + - gci + - gofmt + - goimports + - loggercheck + - goheader + - asasalint + - asciicheck + - bidichk + - contextcheck + - decorder + - dogsled + - errchkjson + - errname + - execinquery + - exportloopref + - ginkgolinter + - gocheckcompilerdirectives + - gofumpt + - goprintffuncname + - importas + - makezero + - mirror + - nakedret + - dupword