Skip to content

Commit

Permalink
Updated Makefile to reflect common structure (#123)
Browse files Browse the repository at this point in the history
* Revised Makefile

* Moved all common configs to common.mk in common-utils

* Fixed issue with gen certs

* Added yq install step to container
  • Loading branch information
massenz authored Jul 21, 2024
1 parent 87b1086 commit cc0eaaf
Showing 7 changed files with 225 additions and 111 deletions.
13 changes: 5 additions & 8 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -16,14 +16,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install YQ
run: |
sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq &&\
sudo chmod +x /usr/bin/yq
- name: Generate Certs
run: |
export GOPATH=/opt/go
mkdir -p $GOPATH/bin
export PATH=$GOPATH/bin:$PATH
go install github.com/cloudflare/cfssl/cmd/[email protected]
go install github.com/cloudflare/cfssl/cmd/[email protected]
make gencert
make certs
- name: Build Container
run: |
make container
@@ -32,10 +36,3 @@ jobs:
mkdir -p ${HOME}/.aws && cp data/credentials ${HOME}/.aws/
export AWS_REGION=us-west-2
go test ./pkg/api ./pkg/grpc ./pkg/pubsub ./pkg/storage
# TODO: need to disable for now, as this fails and I can't figure out why
# - name: Test CLI
# run: |
# mkdir -p ${HOME}/.fsm/certs
# cp certs/ca.pem ${HOME}/.fsm/certs/
# RELEASE=$(make version) BASEDIR=$(pwd) go test ./client
215 changes: 114 additions & 101 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,147 +1,160 @@
# Copyright (c) 2022 AlertAvert.com. All rights reserved.
# Copyright (c) 2022-2024 AlertAvert.com. All rights reserved.
# Created by M. Massenzio, 2022-03-14


GOOS ?= $(shell uname -s | tr "[:upper:]" "[:lower:]")
GOARCH ?= amd64
GOMOD := $(shell go list -m)

version := v0.13.1
release := $(version)-g$(shell git rev-parse --short HEAD)
out := build/bin
server := fsm-server-$(version)_$(GOOS)-$(GOARCH)
cli := fsm-cli-$(version)_$(GOOS)-$(GOARCH)

# CLI Configuration
cli_config := ${HOME}/.fsm

image := massenz/statemachine
compose := docker/compose.yaml
dockerfile := docker/Dockerfile
include thirdparty/common.mk
bin := $(appname)-$(release)_$(GOOS)-$(GOARCH)

# Source files & Test files definitions
#
# Edit only the packages list, when adding new functionality,
# the rest is deduced automatically.
#
pkgs := pkg/api pkg/grpc pkg/pubsub pkg/storage pkg/internal
pkgs := $(shell find pkg -mindepth 1 -type d)
all_go := $(shell for d in $(pkgs); do find $$d -name "*.go"; done)
test_srcs := $(shell for d in $(pkgs); do find $$d -name "*_test.go"; done)
srcs := $(filter-out $(test_srcs),$(all_go))

##@ General

# The help target prints out all targets with their descriptions organized
# beneath their categories. The categories are represented by '##@' and the
# target descriptions by '##'. The awk commands is responsible for reading the
# entire set of makefiles included in this invocation, looking for lines of the
# file as xyz: ## something, and then pretty-format the target and help. Then,
# if there's a line with ##@ something, that gets pretty-printed as a category.
# More info on the usage of ANSI control characters for terminal formatting:
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
# More info on the awk command:
# http://linuxcommand.org/lc3_adv_awk.php

.PHONY: help
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

.PHONY: clean
img=$(shell docker images -q --filter=reference=$(image))
clean: ## Cleans up the binary, container image and other data
@rm $(out)/$(server) $(out)/$(cli)
@[ ! -z $(img) ] && docker rmi $(img) || true
@rm -rf certs
clean: clean-cert ## Cleans up the binary, container image and other data
@rm -rf build/*
@find . -name "*.out" -exec rm {} \;
ifneq (,$(img))
@docker rmi $(img) || true
endif

version: ## Displays the current version tag (release)
@echo $(release)
@echo v$(version)

fmt: ## Formats the Go source code using 'go fmt'
@go fmt $(pkgs) ./cmd fsm-cli/client fsm-cli/cmd

##@ Development
.PHONY: build test container cov clean fmt
$(out)/$(server): cmd/main.go $(srcs)
@mkdir -p $(out)
GOOS=$(GOOS) GOARCH=$(GOARCH) go build \
-ldflags "-X $(GOMOD)/pkg/api.Release=$(release)" \
-o $(out)/$(server) cmd/main.go

.PHONY: build
build: $(out)/$(server) ## Builds the Statemachine server binary

.PHONY: cli
cli: fsm-cli/cmd/main.go ## Builds the CLI client used to connect to the server
@mkdir -p $(out)
cd fsm-cli && GOOS=$(GOOS) GOARCH=$(GOARCH) go build \
-ldflags "-X main.Release=$(version)" \
-o ../$(out)/$(cli) cmd/main.go

.PHONY: cli-test
cli-test: ## Run tests for the CLI Client
@mkdir -p $(cli_config)/certs
@cp certs/ca.pem $(cli_config)/certs || true
cd fsm-cli && RELEASE=$(release) BASEDIR=$(shell pwd) \
CLI_TEST_COMPOSE=$(shell pwd)/docker/cli-test-compose.yaml \
ginkgo test ./client

test: $(srcs) $(test_srcs) ## Runs all tests
ginkgo $(pkgs)

cov: $(srcs) $(test_srcs) ## Runs the Test Coverage and saves the coverage report to out/reports/cov.out
@mkdir -p out/reports
@go test -coverprofile=out/reports/cov.out $(pkgs)
@echo "Coverage report at out/reports/cov.out"
build: cmd/main.go $(srcs) ## Builds the binary
@mkdir -p build/bin
@echo "Building rel. $(release); OS/Arch: $(GOOS)/$(GOARCH) - Pkg: $(GOMOD)"
@GOOS=$(GOOS) GOARCH=$(GOARCH) go build \
-ldflags "-X $(GOMOD)/api.Release=$(release)" \
-o build/bin/$(bin) cmd/main.go
@echo "$(GREEN)[SUCCESS]$(RESET) Binary $(shell basename $(bin)) built"

build/bin/$(bin): build

.PHONY: test
test: $(srcs) $(test_srcs) check_certs ## Runs all tests
@mkdir -p build/reports
ginkgo -keepGoing -cover -coverprofile=coverage.out -outputdir=build/reports $(pkgs)
# Clean up the coverage files (they are not needed once the
# report is generated)
@find ./pkg -name "coverage.out" -exec rm {} \;

.PHONY: watch
watch: $(srcs) $(test_srcs) ## Runs all tests every time a source or test file changes
ginkgo watch -p $(pkgs)

build/reports/coverage.out: test ## Runs all tests and generates the coverage report

.PHONY: coverage
coverage: build/reports/coverage.out ## Shows the coverage report in the browser
@go tool cover -html=build/reports/coverage.out

.PHONY: all
all: build gencert test ## Builds the binary and runs all tests

PORT ?= 7398
.PHONY: dev
dev: build ## Runs the server binary in development mode
# FIXME: this currently does not work and should be adjusted
build/bin/$(bin) -debug -grpc-port $(PORT)

##@ Container Management
# Convenience targets to run locally containers and
# setup the test environments.
image := massenz/$(appname)
compose := docker/compose.yaml
dockerfile := docker/Dockerfile

container: ## Builds the container image
docker build -f $(dockerfile) -t $(image):$(release) .
.PHONY: container
container: build/bin/$(bin) ## Builds the container image
docker build -f $(dockerfile) \
--build-arg="VERSION=$(version)" \
-t $(image):$(release) .
@echo "$(GREEN)[SUCCESS]$(RESET) Container image $(YELLOW)$(image):$(release)$(RESET) built"

.PHONY: start
start: ## Starts the Redis and LocalStack containers, and Creates the SQS Queues in LocalStack
start: ## Runs the container locally
@echo "$(GREEN)[STARTING]$(RESET) Stopping containers"
@RELEASE=$(release) BASEDIR=$(shell pwd) docker compose -f $(compose) --project-name sm up redis localstack -d
@sleep 3
@for queue in events notifications; do \
aws --no-cli-pager --endpoint-url=http://localhost:4566 \
--region us-west-2 \
sqs create-queue --queue-name $$queue; done
@RELEASE=$(release) BASEDIR=$(shell pwd) docker compose -f $(compose) --project-name sm up server
@echo "$(GREEN)[SUCCESS]$(RESET) Containers started"

.PHONY: stop
stop: ## Stops the Redis and LocalStack containers
stop: ## Stops the running containers
@echo "$(RED)[STOPPING]$(RESET) Stopping containers"
@RELEASE=$(release) BASEDIR=$(shell pwd) docker compose -f $(compose) --project-name sm down


##@ TLS Support
#
# This section is WIP and subject to change

config_dir := ssl-config
ca-csr := $(config_dir)/ca-csr.json
ca-config := $(config_dir)/ca-config.json
server-csr := $(config_dir)/localhost-csr.json

.PHONY: gencert
gencert: $(ca-csr) $(ca-config) $(server-csr) ## Generates all certificates in the certs directory (requires cfssl and cfssl, see https://github.com/cloudflare/cfssl#installation)
cfssl gencert \
-initca $(ca-csr) | cfssljson -bare ca


cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=$(ca-config) \
-profile=server \
$(server-csr) | cfssljson -bare server
# Dependency checks for the 'test' target
.PHONY: check_certs
check_certs:
@num_certs=$$(ls -1 certs/*.pem 2>/dev/null | wc -l); \
if [ $$num_certs != 4 ]; then \
echo "$(YELLOW)[WARN]$(RESET) No certificates found in $(shell pwd)/certs"; \
make certs; \
echo "$(GREEN)[SUCCESS]$(RESET) Certificates generated in $(shell pwd)/certs"; \
else \
echo "$(GREEN)[OK]$(RESET) Certificates found in $(shell pwd)/certs"; \
fi

ssl_config := ../ssl-config
ca-csr := $(ssl_config)/ca-csr.json
ca-config := $(ssl_config)/ca-config.json
server-csr := $(ssl_config)/localhost-csr.json

.PHONY: certs
certs: ## Generates all certificates in the certs directory (requires cfssl, see https://github.com/cloudflare/cfssl#installation)
@mkdir -p certs
@mv *.pem certs/
@rm *.csr
@chmod a+r certs/*
@echo "Certificates generated in $(shell pwd)/certs"
@cd certs && \
cfssl gencert \
-initca $(ca-csr) 2>/dev/null | cfssljson -bare ca
@cd certs && \
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=$(ca-config) \
-profile=server \
$(server-csr) 2>/dev/null | cfssljson -bare server
@rm certs/*.csr
@chmod a+r certs/*.pem
@echo "$(GREEN)[SUCCESS]$(RESET) Certificates generated"

.PHONY: clean-cert
clean-cert:
@rm -rf certs

##@ CLI Client
# TODO: move to a separate Makefile in the subdirectory
# See: https://www.gnu.org/software/make/manual/html_node/Recursion.html
# CLI Configuration
cli := out/bin/$(appname)-cli-$(version)_$(GOOS)-$(GOARCH)
cli_config := ${HOME}/.fsm
.PHONY: cli
cli: fsm-cli/cmd/main.go ## Builds the CLI client used to connect to the server
@mkdir -p build/bin
cd fsm-cli && GOOS=$(GOOS) GOARCH=$(GOARCH) go build \
-ldflags "-X main.Release=$(release)" \
-o ../build/bin/$(cli) cmd/main.go

.PHONY: cli-test
cli-test: ## Run tests for the CLI Client
@mkdir -p $(cli_config)/certs
@cp certs/ca.pem $(cli_config)/certs || true
cd fsm-cli && RELEASE=$(release) BASEDIR=$(shell pwd) \
CLI_TEST_COMPOSE=$(shell pwd)/docker/cli-test-compose.yaml \
ginkgo test ./client
4 changes: 3 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Copyright AlertAvert.com (c) 2023
# Created by M. Massenzio, 2022-04-28

FROM golang:1.21 as builder
FROM golang:1.22 as builder

WORKDIR /server
COPY . .
RUN rm -rf certs data
RUN wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 \
-O /usr/bin/yq && chmod +x /usr/bin/yq
RUN CGO_ENABLED=0 make build
RUN CGO_ENABLED=0 go build -o build/bin/hc docker/grpc_health.go

2 changes: 1 addition & 1 deletion docker/compose.yaml
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ services:
- sm-net
ports:
- '7398:7398'
image: "massenz/statemachine:${RELEASE}"
image: "massenz/fsm-server:${RELEASE}"
environment:
AWS_ENDPOINT: "http://awslocal:4566"
AWS_REGION: us-west-2
10 changes: 10 additions & 0 deletions settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright (c) 2023-2024 AlertAvert.com
# All rights reserved.
# Created by Marco Massenzio, 2023-07-13

name: fsm-server
version: 0.12.2
description: A StateMachine gRPC server, backed by Redis storage
author: Marco Massenzio ([email protected])
license: Apache-2.0
url: https://alertavert.com/statemachine
9 changes: 9 additions & 0 deletions thirdparty/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Third-Party Libraries

## common.mk

This file is a makefile that contains common rules for building and testing
copied from the [`common-utils`](https://github.com/massenz/common-utils) repository.

It needs to be copied here as it cannot be included in `Makefile` directly from the
original repository.
Loading

0 comments on commit cc0eaaf

Please sign in to comment.