495 lines
16 KiB
Makefile
495 lines
16 KiB
Makefile
# Go Bananas!!
|
|
#
|
|
# The Makefile is the primary interface to this repository. Every task a developer
|
|
# or a CI job needs is a target here, and each target is safe to run repeatedly.
|
|
#
|
|
# Conventions:
|
|
# * `make help` lists everything.
|
|
# * Targets are grouped by phase and the phases run in order for `make all`.
|
|
# * Anything that changes the machine (installing a tool, pushing an image) is
|
|
# marked ##@destructive so it is obvious in `make help`.
|
|
# * Variables at the top are overridable: `make IMAGE_TAG=v2 build`.
|
|
#
|
|
# The `##@` markers are read by the self-documenting help target, which is why
|
|
# they are inline comments rather than a separate block.
|
|
|
|
SHELL := /usr/bin/env bash
|
|
.SHELLFLAGS := -eu -o pipefail -c
|
|
.DEFAULT_GOAL := help
|
|
.DELETE_ON_ERROR:
|
|
.SUFFIXES:
|
|
|
|
# --------------------------------------------------------------- variables ----
|
|
|
|
BINARY := go-bananas
|
|
CMD := ./cmd/go-bananas
|
|
BIN_DIR := bin
|
|
DIST_DIR := dist
|
|
WEB_DIR := web
|
|
SDK_DIR := sdk
|
|
|
|
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
|
|
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
|
BUILD_DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
|
|
REGISTRY ?= nexus.urpi.be/docker-hosted
|
|
IMAGE_NAME ?= $(REGISTRY)/$(BINARY)
|
|
IMAGE_TAG ?= $(VERSION)
|
|
PLATFORM ?= linux/amd64,linux/arm64
|
|
|
|
GO ?= go
|
|
NPM ?= npm
|
|
|
|
# Development tool versions, pinned so that every contributor and every CI run use
|
|
# the same linter. They are pinned here rather than in a separate tools module
|
|
# because `go install pkg@version` resolves the version itself and refuses a
|
|
# -modfile, which would make a tools.mod decorative rather than binding. `make
|
|
# tools-upgrade` bumps all three in one place.
|
|
AIR_VERSION ?= v1.67.4
|
|
GOLANGCI_VERSION ?= v2.14.0
|
|
SQLC_VERSION ?= v1.31.1
|
|
HELM ?= helm
|
|
DOCKER ?= docker
|
|
|
|
# Module cache and build cache live outside the tree so that a bind-mounted
|
|
# working directory does not slowly fill the developer's disk.
|
|
GO_CACHE ?= $(CURDIR)/.cache/go-build
|
|
GOMODCACHE ?= $(CURDIR)/.cache/go-mod
|
|
|
|
# The Go packages belonging to this module, excluding the JavaScript trees.
|
|
#
|
|
# Go does not ignore node_modules: any directory under the module root with Go
|
|
# files in it is part of `./...`, and a dependency that happens to ship a stray
|
|
# package would then be compiled and linted as if it were ours. `./internal/...`
|
|
# and `./cmd/...` are listed instead of filtering, so the omission is visible here
|
|
# rather than hidden in a pipe.
|
|
GO_PACKAGES = ./cmd/... ./internal/...
|
|
|
|
# The full set of ldflags. Kept in one variable so that `go build`, `go install`
|
|
# and goreleaser cannot drift apart and produce differently-identified binaries.
|
|
LDFLAGS := -s -w \
|
|
-X github.com/urpi/go-bananas/internal/app.Version=$(VERSION) \
|
|
-X github.com/urpi/go-bananas/internal/app.Commit=$(COMMIT) \
|
|
-X github.com/urpi/go-bananas/internal/app.BuildDate=$(BUILD_DATE)
|
|
|
|
GOFLAGS_BUILD := -trimpath -ldflags "$(LDFLAGS)"
|
|
|
|
.DEFAULT_COLOR := \033[0m
|
|
.BOLD := \033[1m
|
|
.DIM := \033[2m
|
|
.GREEN := \033[32m
|
|
.YELLOW := \033[33m
|
|
.RED := \033[31m
|
|
|
|
##@ General
|
|
|
|
.PHONY: help
|
|
help: ## Show this help
|
|
@printf "$(BOLD)go-bananas$(DEFAULT_COLOR) — runtime design-token service\n\n"
|
|
@printf "$(DIM)Version$(DEFAULT_COLOR) $(VERSION) ($(COMMIT))\n\n"
|
|
@# The awk pass reads both the "##@" group markers and the "##" target help in
|
|
@# one scan so that groups appear in file order rather than in two separate
|
|
@# alphabetical lists. A trailing "##@destructive" is stripped from the
|
|
@# description and rendered as a marker instead.
|
|
@awk 'BEGIN {FS = ":.*##"} \
|
|
/^##@/ { printf "\n$(BOLD)%s$(DEFAULT_COLOR)\n", substr($$0, 5); next } \
|
|
/^[a-zA-Z0-9_-]+:.*?##/ { \
|
|
help = $$0; sub(/^[^:]*:.*## /, "", help); \
|
|
mark = ""; \
|
|
if (help ~ /##@destructive/) { mark = "$(YELLOW) [modifies this machine]$(DEFAULT_COLOR)"; \
|
|
sub(/ *##@destructive/, "", help) } \
|
|
printf " $(BOLD)%-20s$(DEFAULT_COLOR) %s%s\n", $$1, help, mark \
|
|
}' $(MAKEFILE_LIST)
|
|
@printf "\n$(DIM)Override any variable, e.g. make IMAGE_TAG=v2.1.0 image-push$(DEFAULT_COLOR)\n"
|
|
|
|
.PHONY: version
|
|
version: ## Print the version that would be built
|
|
@echo "$(VERSION) ($(COMMIT)) built $(BUILD_DATE)"
|
|
|
|
##@ Development
|
|
|
|
.PHONY: install
|
|
install: ## Install Go and Node dependencies
|
|
$(GO) mod download
|
|
cd $(WEB_DIR) && $(NPM) install
|
|
cd $(SDK_DIR) && $(NPM) install
|
|
|
|
.PHONY: dev
|
|
dev: ## Run the API with hot reload (Ctrl-C to stop)
|
|
@command -v air >/dev/null 2>&1 || { \
|
|
echo "air is not installed; run 'make tools' or see docs/development.md"; exit 1; }
|
|
@BANANAS_ENVIRONMENT=development \
|
|
BANANAS_AUTH_MODE=dev \
|
|
BANANAS_HTTP_ADDR=:8080 \
|
|
BANANAS_DATABASE_PATH=./data/go-bananas.db \
|
|
BANANAS_STATIC_DIR=$(WEB_DIR)/dist \
|
|
BANANAS_SDK_DIR=$(SDK_DIR)/dist \
|
|
air -c .air.toml
|
|
|
|
.PHONY: dev-api
|
|
dev-api: ## Run the API (no SPA); Vite serves the UI, this serves the runtime SDK
|
|
@BANANAS_ENVIRONMENT=development \
|
|
BANANAS_AUTH_MODE=dev \
|
|
BANANAS_HTTP_ADDR=:8080 \
|
|
BANANAS_DATABASE_PATH=./data/go-bananas.db \
|
|
BANANAS_STATIC_DIR= \
|
|
BANANAS_SDK_DIR=$(SDK_DIR)/dist \
|
|
$(GO) run -ldflags "$(LDFLAGS)" $(CMD)
|
|
|
|
.PHONY: dev-web
|
|
dev-web: ## Run the Vite dev server for the admin UI, proxying the API
|
|
cd $(WEB_DIR) && $(NPM) run dev
|
|
|
|
.PHONY: dev-all
|
|
dev-all: build-sdk ## Run the API and the frontend dev server together
|
|
@echo "API on http://localhost:8080, admin UI on http://localhost:5173"
|
|
@trap 'kill 0' EXIT; \
|
|
$(MAKE) dev-api & \
|
|
$(MAKE) dev-web & \
|
|
wait
|
|
|
|
.PHONY: tools
|
|
tools: ## Install the pinned development tools (air, golangci-lint, sqlc) ##@destructive
|
|
$(GO) install github.com/air-verse/air@$(AIR_VERSION)
|
|
$(GO) install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_VERSION)
|
|
$(GO) install github.com/sqlc-dev/sqlc/cmd/sqlc@$(SQLC_VERSION)
|
|
@echo "Tools installed into $$( $(GO) env GOBIN )"
|
|
@echo "golangci-lint $(GOLANGCI_VERSION), air $(AIR_VERSION), sqlc $(SQLC_VERSION)"
|
|
|
|
.PHONY: tools-upgrade
|
|
tools-upgrade: ## Bump the pinned development tools to their latest releases ##@destructive
|
|
@for tool in \
|
|
github.com/air-verse/air:AIR_VERSION \
|
|
github.com/golangci/golangci-lint/v2:GOLANGCI_VERSION \
|
|
github.com/sqlc-dev/sqlc:SQLC_VERSION; do \
|
|
pkg=$${tool%%:*}; var=$${tool##*:}; \
|
|
latest=$$($(GO) list -m -versions $$pkg | tr ' ' '\n' | tail -1); \
|
|
[ -n "$$latest" ] || { echo "could not resolve $$pkg"; exit 1; }; \
|
|
sed -i.bak "s|^$$var .*|$$var ?= $$latest|" Makefile && rm -f Makefile.bak; \
|
|
echo "$$var -> $$latest"; \
|
|
done
|
|
@echo "Run 'make tools' to install them and commit the Makefile change."
|
|
|
|
.PHONY: clean
|
|
clean: ## Remove build output and local data
|
|
rm -rf $(BIN_DIR) $(DIST_DIR) data .cache
|
|
cd $(WEB_DIR) && rm -rf dist
|
|
cd $(SDK_DIR) && rm -rf dist
|
|
@echo "Cleaned."
|
|
|
|
.PHONY: clean-cache
|
|
clean-cache: ## Remove every build cache, including the module cache ##@destructive
|
|
$(GO) clean -cache -modcache
|
|
rm -rf .cache
|
|
cd $(WEB_DIR) && rm -rf node_modules/.vite
|
|
cd $(SDK_DIR) && rm -rf node_modules/.vite
|
|
|
|
##@ Build
|
|
|
|
.PHONY: build
|
|
build: build-go build-web build-sdk ## Build every artefact
|
|
|
|
.PHONY: build-go
|
|
build-go: ## Build the server binary into bin/
|
|
@mkdir -p $(BIN_DIR)
|
|
CGO_ENABLED=0 $(GO) build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/$(BINARY) $(CMD)
|
|
@echo "Built $(BIN_DIR)/$(BINARY)"
|
|
|
|
.PHONY: build-web
|
|
build-web: ## Build the admin UI into web/dist
|
|
cd $(WEB_DIR) && $(NPM) run build
|
|
|
|
.PHONY: build-sdk
|
|
build-sdk: ## Build the runtime SDK bundles into sdk/dist
|
|
cd $(SDK_DIR) && $(NPM) run build
|
|
|
|
.PHONY: run
|
|
run: build-go ## Build and run the server with the current assets
|
|
@mkdir -p data
|
|
BANANAS_ENVIRONMENT=development \
|
|
BANANAS_AUTH_MODE=dev \
|
|
BANANAS_STATIC_DIR=$(WEB_DIR)/dist \
|
|
BANANAS_SDK_DIR=$(SDK_DIR)/dist \
|
|
./$(BIN_DIR)/$(BINARY)
|
|
|
|
.PHONY: release
|
|
release: ## Build release binaries for every supported platform ##@destructive
|
|
@command -v goreleaser >/dev/null 2>&1 || { \
|
|
echo "goreleaser is not installed; see docs/development.md"; exit 1; }
|
|
goreleaser release --clean
|
|
|
|
.PHONY: release-snapshot
|
|
release-snapshot: ## Build release binaries without publishing ##@destructive
|
|
goreleaser release --snapshot --clean --skip=publish
|
|
|
|
.PHONY: sbom
|
|
sbom: ## Generate a CycloneDX SBOM for the current version ##@destructive
|
|
@command -v syft >/dev/null 2>&1 || { \
|
|
echo "syft is not installed"; exit 1; }
|
|
syft dir:. -o cyclonedx-json=sbom-$(VERSION).json
|
|
|
|
##@ Quality
|
|
|
|
.PHONY: check
|
|
check: fmt-check lint test ## Run every check
|
|
|
|
.PHONY: fmt
|
|
fmt: ## Format the Go code
|
|
$(GO) fmt ./...
|
|
|
|
.PHONY: fmt-check
|
|
fmt-check: ## Fail if the Go code is not formatted
|
|
@unformatted="$$(gofmt -l . | grep -v '^vendor/' || true)"; \
|
|
if [ -n "$$unformatted" ]; then \
|
|
echo "These files are not gofmt'd:"; echo "$$unformatted"; exit 1; \
|
|
fi
|
|
@echo "Go formatting is clean."
|
|
|
|
.PHONY: lint
|
|
lint: lint-go lint-web lint-sdk ## Run every linter
|
|
|
|
.PHONY: lint-go
|
|
lint-go: ## Run golangci-lint
|
|
@command -v golangci-lint >/dev/null 2>&1 || { \
|
|
echo "golangci-lint is not installed; run 'make tools'"; exit 1; }
|
|
golangci-lint run $(GO_PACKAGES)
|
|
|
|
.PHONY: lint-web
|
|
lint-web: ## Lint and typecheck the admin UI
|
|
cd $(WEB_DIR) && $(NPM) run lint
|
|
cd $(WEB_DIR) && $(NPM) run typecheck
|
|
|
|
.PHONY: lint-sdk
|
|
lint-sdk: ## Lint and typecheck the runtime SDK
|
|
cd $(SDK_DIR) && $(NPM) run typecheck
|
|
|
|
.PHONY: fmt-web
|
|
fmt-web: ## Format the frontend and SDK sources
|
|
cd $(WEB_DIR) && $(NPM) run format
|
|
cd $(SDK_DIR) && $(NPM) exec prettier --write .
|
|
|
|
.PHONY: tidy
|
|
tidy: ## Tidy the Go module
|
|
$(GO) mod tidy
|
|
|
|
##@ Test
|
|
|
|
.PHONY: test
|
|
test: test-go test-web test-sdk ## Run every test suite
|
|
|
|
.PHONY: test-go
|
|
test-go: ## Run the Go tests
|
|
$(GO) test -race -count=1 $(GO_PACKAGES)
|
|
|
|
.PHONY: test-cover
|
|
test-cover: ## Run the Go tests and write a coverage profile
|
|
$(GO) test -race -count=1 -coverprofile=coverage.out -covermode=atomic $(GO_PACKAGES)
|
|
$(GO) tool cover -func=coverage.out | tail -1
|
|
@echo "Profile written to coverage.out"
|
|
|
|
.PHONY: test-web
|
|
test-web: ## Run the admin UI tests
|
|
cd $(WEB_DIR) && $(NPM) test
|
|
|
|
.PHONY: test-sdk
|
|
test-sdk: ## Run the runtime SDK tests
|
|
cd $(SDK_DIR) && $(NPM) test
|
|
|
|
.PHONY: bench
|
|
bench: ## Run the token engine benchmarks
|
|
$(GO) test -bench=. -benchmem ./internal/tokenengine/
|
|
|
|
##@ Docker
|
|
|
|
.PHONY: image
|
|
image: ## Build the container image for the host architecture
|
|
$(DOCKER) buildx build \
|
|
--build-arg VERSION=$(VERSION) \
|
|
--build-arg COMMIT=$(COMMIT) \
|
|
--build-arg BUILD_DATE=$(BUILD_DATE) \
|
|
--tag $(IMAGE_NAME):$(IMAGE_TAG) \
|
|
--tag $(IMAGE_NAME):latest \
|
|
--load \
|
|
.
|
|
|
|
.PHONY: image-multi
|
|
image-multi: ## Build the multi-architecture image without pushing ##@destructive
|
|
$(DOCKER) buildx build \
|
|
--platform $(PLATFORM) \
|
|
--build-arg VERSION=$(VERSION) \
|
|
--build-arg COMMIT=$(COMMIT) \
|
|
--build-arg BUILD_DATE=$(BUILD_DATE) \
|
|
--tag $(IMAGE_NAME):$(IMAGE_TAG) \
|
|
.
|
|
|
|
.PHONY: image-push
|
|
image-push: ## Build and push the multi-architecture image ##@destructive
|
|
$(DOCKER) buildx build \
|
|
--platform $(PLATFORM) \
|
|
--build-arg VERSION=$(VERSION) \
|
|
--build-arg COMMIT=$(COMMIT) \
|
|
--build-arg BUILD_DATE=$(BUILD_DATE) \
|
|
--push \
|
|
--tag $(IMAGE_NAME):$(IMAGE_TAG) \
|
|
.
|
|
|
|
.PHONY: image-run
|
|
image-run: ## Run the image locally on port 8080
|
|
$(DOCKER) run --rm -it \
|
|
-p 8080:8080 \
|
|
-e BANANAS_ENVIRONMENT=development \
|
|
-e BANANAS_AUTH_MODE=dev \
|
|
-v go-bananas-data:/srv/data \
|
|
$(IMAGE_NAME):$(IMAGE_TAG)
|
|
|
|
.PHONY: compose-up
|
|
compose-up: ## Start the local stack with docker compose
|
|
$(DOCKER) compose up --build
|
|
|
|
.PHONY: compose-down
|
|
compose-down: ## Stop the local stack ##@destructive
|
|
$(DOCKER) compose down
|
|
|
|
.PHONY: compose-logs
|
|
compose-logs: ## Follow the local stack logs
|
|
$(DOCKER) compose logs -f
|
|
|
|
.PHONY: compose-shell
|
|
compose-shell: ## Open a shell in the running service ##@destructive
|
|
$(DOCKER) compose exec go-bananas /bin/sh
|
|
|
|
##@ Helm
|
|
|
|
.PHONY: helm-lint
|
|
helm-lint: ## Lint the chart
|
|
$(HELM) lint deploy/helm/go-bananas --strict
|
|
|
|
.PHONY: helm-matrix
|
|
helm-matrix: ## Render the chart across a matrix of valid and invalid configurations
|
|
./hack/helm-matrix.sh
|
|
|
|
.PHONY: helm-template
|
|
helm-template: ## Render the chart with the default values
|
|
$(HELM) template go-bananas deploy/helm/go-bananas
|
|
|
|
.PHONY: helm-template-auth
|
|
helm-template-auth: ## Render the chart configured for OIDC
|
|
$(HELM) template go-bananas deploy/helm/go-bananas \
|
|
--set identity.mode=oidc \
|
|
--set identity.oidc.issuer=https://auth.lcl-urpi.be/realms/urpi \
|
|
--set identity.oidc.clientId=go-bananas \
|
|
--set identity.oidc.generateSecret=false \
|
|
--set identity.oidc.existingSecret=go-bananas-oidc \
|
|
--set config.publicBaseUrl=https://themes-dev.example.com
|
|
|
|
.PHONY: helm-install
|
|
helm-install: ## Install the chart into the current kube context ##@destructive
|
|
$(HELM) upgrade --install go-bananas deploy/helm/go-bananas \
|
|
--namespace go-bananas --create-namespace \
|
|
--values deploy/helm/go-bananas/values.yaml \
|
|
--wait --timeout 5m
|
|
|
|
.PHONY: helm-uninstall
|
|
helm-uninstall: ## Remove the release ##@destructive
|
|
$(HELM) uninstall go-bananas --namespace go-bananas
|
|
|
|
##@ Local (lcl)
|
|
|
|
# The lcl environment is the developer's local k3s cluster with a registry at
|
|
# localhost:5000 and a TLS edge serving *.intern-urpi.be. go-* apps deploy into the
|
|
# shared `go-insane-lcl` namespace. These targets use values-lcl.yaml.
|
|
#
|
|
# KUBECONFIG — the lcl kubeconfig. On this box the `local` kubecontext goes through a
|
|
# Rancher proxy that can 502; the direct k3s config is /etc/rancher/k3s/k3s.yaml.
|
|
# Set it to deploy without depending on the proxy: KUBECONFIG=/etc/rancher/k3s/k3s.yaml make deploy-lcl
|
|
# LCL_TAG — image tag. Defaults to a timestamp so a rebuild is always re-pulled;
|
|
# `IfNotPresent` would otherwise serve a stale `0.0.1` from the node cache.
|
|
|
|
LCL_REGISTRY ?= localhost:5000
|
|
LCL_REPO ?= go-bananas
|
|
LCL_TAG ?= $(shell date -u +%Y%m%d%H%M%S)
|
|
LCL_NAMESPACE ?= go-insane-lcl
|
|
LCL_VALUES = deploy/helm/go-bananas/values-lcl.yaml
|
|
|
|
.PHONY: image-lcl
|
|
image-lcl: ## Build and push the image to the local registry ##@destructive
|
|
$(DOCKER) buildx build \
|
|
--build-arg VERSION=$(VERSION) \
|
|
--build-arg COMMIT=$(COMMIT) \
|
|
--build-arg BUILD_DATE=$(BUILD_DATE) \
|
|
--tag $(LCL_REGISTRY)/$(LCL_REPO):$(LCL_TAG) \
|
|
--push \
|
|
.
|
|
|
|
.PHONY: helm-template-lcl
|
|
helm-template-lcl: ## Render the lcl Helm manifest
|
|
$(HELM) template go-bananas deploy/helm/go-bananas \
|
|
--namespace $(LCL_NAMESPACE) \
|
|
--values $(LCL_VALUES) \
|
|
--set-string image.tag=$(LCL_TAG)
|
|
|
|
.PHONY: helm-install-lcl
|
|
helm-install-lcl: ## Deploy go-bananas to the local (lcl) environment ##@destructive
|
|
$(HELM) upgrade --install go-bananas deploy/helm/go-bananas \
|
|
--namespace $(LCL_NAMESPACE) --create-namespace \
|
|
--values $(LCL_VALUES) \
|
|
--set-string image.tag=$(LCL_TAG) \
|
|
--wait --timeout 5m
|
|
|
|
.PHONY: helm-uninstall-lcl
|
|
helm-uninstall-lcl: ## Remove the lcl release ##@destructive
|
|
$(HELM) uninstall go-bananas --namespace $(LCL_NAMESPACE)
|
|
|
|
.PHONY: deploy-lcl
|
|
deploy-lcl: image-lcl helm-install-lcl ## Build, push, deploy to lcl, then verify ##@destructive
|
|
@echo "waiting for rollout ($(LCL_NAMESPACE)/go-bananas)..."
|
|
@kubectl -n $(LCL_NAMESPACE) rollout status deploy/go-bananas --timeout=120s
|
|
@echo "=== runtime manifest through the TLS edge ==="
|
|
@curl -sk https://bananas-lcl.intern-urpi.be/rt/v1/manifest.json -o /dev/null -w 'manifest.json -> %{http_code}\n' || true
|
|
@echo "deployed image: $(LCL_REGISTRY)/$(LCL_REPO):$(LCL_TAG)"
|
|
|
|
##@ Docs
|
|
|
|
.PHONY: docs-serve
|
|
docs-serve: ## Serve the documentation locally
|
|
@command -v mkdocs >/dev/null 2>&1 || { echo "mkdocs is not installed"; exit 1; }
|
|
mkdocs serve
|
|
|
|
.PHONY: docs-build
|
|
docs-build: ## Build the documentation ##@destructive
|
|
mkdocs build --strict
|
|
|
|
.PHONY: api-spec
|
|
api-spec: ## Print the OpenAPI document summary
|
|
@grep -E '^\s{2}/' openapi.yaml | sed 's/:$//' | tr -d ' ' | sed 's|^| |'
|
|
|
|
##@ Contract
|
|
|
|
.PHONY: check-contract
|
|
check-contract: ## Drive the shared styling contract and the shipped controls in a real browser ##@destructive
|
|
./hack/check-contract.sh
|
|
|
|
.PHONY: check-pilot
|
|
check-pilot: ## Prove both adopting applications follow the contract without editing their CSS ##@destructive
|
|
./hack/check-pilot-go-loose.sh
|
|
./hack/check-pilot-go-tell.sh
|
|
|
|
##@ CI helpers
|
|
|
|
.PHONY: ci
|
|
ci: check ## Everything CI runs, in one target
|
|
|
|
.PHONY: verify
|
|
verify: ci helm-lint helm-matrix check-contract check-pilot ## The full pre-merge gate
|
|
|
|
.PHONY: deps-outdated
|
|
deps-outdated: ## Report outdated Go and Node dependencies
|
|
$(GO) list -u -m all
|
|
@echo
|
|
cd $(WEB_DIR) && $(NPM) outdated || true
|
|
|
|
.PHONY: deps-update
|
|
deps-update: ## Update Go and Node dependencies ##@destructive
|
|
$(GO) get -u ./... && $(GO) mod tidy
|
|
cd $(WEB_DIR) && $(NPM) update
|
|
cd $(SDK_DIR) && $(NPM) update
|