Files
gotenberg/Makefile
Julien Neuhart 8a0de7d5d7 build(makefile): disable two go fix modernizers that emit broken code
go fix runs the modernize suite since Go 1.26, and two of its analyzers
rewrite this codebase into code that does not compile, so make fmt broke
the build and then make lint. CONTRIBUTING tells every contributor to run
both before opening a PR.

embedlit folded telemetryCfg.LogLevel into a literal that already set that
key, and errorsastype rewrote errors.As to errors.AsType[HttpError] even
though HttpError does not embed error. Disable both, with a TODO covering
when each can come back.
2026-09-03 19:22:23 +02:00

243 lines
7.2 KiB
Makefile

include .env
.PHONY: help
help: ## Show the help
@grep -hE '^[A-Za-z0-9_ \-]*?:.*##.*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.PHONY: build
build: ## Build the Gotenberg's Docker image (use TARGET=gotenberg-chromium or TARGET=gotenberg-libreoffice for variants)
docker build \
--target $(TARGET) \
-t $(DOCKER_REGISTRY)/$(DOCKER_REPOSITORY):$(GOTENBERG_VERSION) \
-f $(DOCKERFILE) $(DOCKER_BUILD_CONTEXT)
TZ=UTC
GOTENBERG_HIDE_BANNER=false
GOTENBERG_GRACEFUL_SHUTDOWN_DURATION=30s
GOTENBERG_BUILD_DEBUG_DATA=true
API_PORT=3000
API_PORT_FROM_ENV=
API_BIND_IP=
API_TLS_CERT_FILE=
API_TLS_KEY_FILE=
API_START_TIMEOUT=30s
API_TIMEOUT=30s
API_BODY_LIMIT=
API_ROOT_PATH=/
API_CORRELATION_ID_HEADER=Gotenberg-Trace
API_ENABLE_BASIC_AUTH=false
GOTENBERG_API_BASIC_AUTH_USERNAME=
GOTENBERG_API_BASIC_AUTH_PASSWORD=
API_ENABLE_OIDC_AUTH=false
API_OIDC_ISSUER=
API_OIDC_AUDIENCE=
API_OIDC_JWKS_URL=
API_DOWNLOAD_FROM_ALLOW_LIST=
API_DOWNLOAD_FROM_DENY_LIST=^https?://(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|169\.254\.|0\.0\.0\.0|127\.|localhost|\[::1\]|\[fd)
API_DOWNLOAD_FROM_DENY_PRIVATE_IPS=false
API_DOWNLOAD_FROM_DENY_PUBLIC_IPS=false
API_DOWNLOAD_FROM_ENABLE_ENVIRONMENT_PROXY=false
API_DOWNLOAD_FROM_MAX_RETRY=4
API_DOWNLOAD_FROM_MAX_CONCURRENCY=10
API_DOWNLOAD_FROM_MAX_ENTRIES=0
API_DISABLE_DOWNLOAD_FROM=false
API_DISABLE_HEALTH_CHECK_ROUTE_TELEMETRY=true
API_DISABLE_ROOT_ROUTE_TELEMETRY=true
API_DISABLE_DEBUG_ROUTE_TELEMETRY=true
API_DISABLE_VERSION_ROUTE_TELEMETRY=true
API_ENABLE_DEBUG_ROUTE=false
CHROMIUM_RESTART_AFTER=100
CHROMIUM_MAX_QUEUE_SIZE=0
CHROMIUM_IDLE_SHUTDOWN_TIMEOUT=0
CHROMIUM_MAX_CONCURRENCY=6
CHROMIUM_AUTO_START=false
CHROMIUM_START_TIMEOUT=20s
CHROMIUM_ALLOW_INSECURE_LOCALHOST=false
CHROMIUM_IGNORE_CERTIFICATE_ERRORS=false
CHROMIUM_DISABLE_WEB_SECURITY=false
CHROMIUM_ALLOW_FILE_ACCESS_FROM_FILES=false
CHROMIUM_HOST_RESOLVER_RULES=
CHROMIUM_PROXY_SERVER=
CHROMIUM_ENABLE_ENVIRONMENT_PROXY=false
CHROMIUM_ALLOW_LIST=
CHROMIUM_DENY_LIST=^file:(?!//\/tmp/).*
CHROMIUM_DENY_PRIVATE_IPS=false
CHROMIUM_DENY_PUBLIC_IPS=false
CHROMIUM_CLEAR_CACHE=false
CHROMIUM_CLEAR_COOKIES=false
CHROMIUM_DISABLE_JAVASCRIPT=false
CHROMIUM_DISABLE_ROUTES=false
LIBREOFFICE_RESTART_AFTER=10
LIBREOFFICE_MAX_QUEUE_SIZE=0
LIBREOFFICE_IDLE_SHUTDOWN_TIMEOUT=0
LIBREOFFICE_AUTO_START=false
LIBREOFFICE_START_TIMEOUT=20s
LIBREOFFICE_ALLOW_LIST=
LIBREOFFICE_DENY_LIST=
LIBREOFFICE_DENY_PRIVATE_IPS=false
LIBREOFFICE_DENY_PUBLIC_IPS=false
LIBREOFFICE_ENABLE_ENVIRONMENT_PROXY=false
LIBREOFFICE_DISABLE_ROUTES=false
LOG_LEVEL=info
LOG_FIELDS_PREFIX=
LOG_STD_FORMAT=auto
LOG_STD_ENABLE_GCP_FIELDS=false
LOG_STD_LEVEL_CASE=lower
PDFENGINES_DISABLE_ROUTES=false
PDFENGINES_MERGE_ENGINES=qpdf,pdfcpu,pdftk
PDFENGINES_SPLIT_ENGINES=pdfcpu,qpdf,pdftk
PDFENGINES_FLATTEN_ENGINES=qpdf
PDFENGINES_CONVERT_ENGINES=libreoffice-pdfengine
PDFENGINES_OPTIMIZE_IMAGES_ENGINES=pdfcpu
PDFENGINES_READ_METADATA_ENGINES=exiftool
PDFENGINES_WRITE_METADATA_ENGINES=exiftool
PDFENGINES_READ_BOOKMARKS_ENGINES=pdfcpu
PDFENGINES_WRITE_BOOKMARKS_ENGINES=pdfcpu
PDFENGINES_WATERMARK_ENGINES=pdfcpu,pdftk
PDFENGINES_STAMP_ENGINES=pdfcpu,pdftk
PDFENGINES_ENCRYPT_ENGINES=qpdf,pdfcpu,pdftk
PDFENGINES_ROTATE_ENGINES=pdfcpu,pdftk
PDFENGINES_EMBED_ENGINES=pdfcpu
PDFENGINES_EMBED_METADATA_ENGINES=qpdf
PDFENGINES_FACTUR_X_ENGINES=qpdf
PROMETHEUS_NAMESPACE=gotenberg
PROMETHEUS_COLLECT_INTERVAL=1s
PROMETHEUS_DISABLE_ROUTE_TELEMETRY=true
PROMETHEUS_DISABLE_COLLECT=false
PROMETHEUS_METRICS_PATH=/prometheus/metrics
OTEL_SERVICE_NAME=gotenberg
OTEL_TRACES_EXPORTER=none
OTEL_METRICS_EXPORTER=none
OTEL_LOGS_EXPORTER=none
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
OTEL_EXPORTER_OTLP_INSECURE=true
WEBHOOK_ENABLE_SYNC_MODE=false
WEBHOOK_ALLOW_LIST=
WEBHOOK_DENY_LIST=^https?://(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|169\.254\.|0\.0\.0\.0|127\.|localhost|\[::1\]|\[fd)
WEBHOOK_DENY_PRIVATE_IPS=false
WEBHOOK_DENY_PUBLIC_IPS=false
WEBHOOK_ENABLE_ENVIRONMENT_PROXY=false
WEBHOOK_MAX_RETRY=4
WEBHOOK_RETRY_MIN_WAIT=1s
WEBHOOK_RETRY_MAX_WAIT=30s
WEBHOOK_CLIENT_TIMEOUT=30s
WEBHOOK_DISABLE=false
# Export all variables so they are available to Compose
export
.PHONY: run
run: ## Start a Gotenberg container via Compose
docker compose up gotenberg
.PHONY: telemetry
telemetry: ## Start an OpenTelemetry collector and OpenObserve containers via Compose
docker compose up otel-collector openobserve
.PHONY: down
down: ## Stop all containers
docker compose down -v
.PHONY: test-unit
test-unit: ## Run unit tests
go test -race ./...
PLATFORM=
NO_CONCURRENCY=false
# Available tags:
# chromium
# chromium-concurrent
# chromium-convert-html
# chromium-convert-markdown
# chromium-convert-url
# chromium-screenshot-html
# chromium-screenshot-markdown
# chromium-screenshot-url
# chromium-ssrf
# debug
# health
# libreoffice
# libreoffice-convert
# libreoffice-ssrf
# output-filename
# pdfengines
# pdfengines-convert
# pdfengines-embed
# embed
# pdfengines-encrypt
# encrypt
# pdfengines-flatten
# flatten
# pdfengines-optimize
# optimize
# pdfengines-merge
# merge
# pdfengines-metadata
# metadata
# pdfengines-split
# split
# pdfengines-watermark
# watermark
# pdfengines-stamp
# stamp
# pdfengines-rotate
# rotate
# factur-x
# pdfengines-bookmarks
# bookmarks
# prometheus-metrics
# root
# version
# webhook
# download-from
TAGS=
.PHONY: test-integration
test-integration: ## Run integration tests (automatically retries failed scenarios up to 3 times)
go test -timeout 40m -tags=integration -v github.com/gotenberg/gotenberg/v8/test/integration -args \
--gotenberg-docker-repository=$(DOCKER_REPOSITORY) \
--gotenberg-version=$(GOTENBERG_VERSION) \
--gotenberg-container-platform=$(PLATFORM) \
--no-concurrency=$(NO_CONCURRENCY) \
--tags="$(TAGS)"
.PHONY: lint
lint: ## Lint Golang codebase
golangci-lint run
.PHONY: lint-prettier
lint-prettier: ## Lint non-Golang codebase
npx prettier --check .
.PHONY: lint-todo
lint-todo: ## Find TODOs in Golang codebase
golangci-lint run --no-config --disable-all --enable godox
# TODO: restore a plain "go fix ./..." once both modernizers stop rewriting this
# codebase into code that does not compile. Re-check by dropping a flag and
# running "make fmt && make lint". Removing an analyzer upstream makes go fix
# fail with "flag provided but not defined", so this cannot rot silently.
# embedlit folds a post-literal field assignment into a literal that already
# sets that key, producing a duplicate field name (cmd/gotenberg.go). Fixed in
# Go 1.27.1, so drop that flag once the toolchain moves past 1.27.0.
# See https://github.com/golang/go/issues/81101.
# errorsastype rewrites errors.As to errors.AsType[T] without checking that T
# satisfies error, which breaks on api.HttpError since it does not embed
# error. Still broken as of Go 1.27.1.
.PHONY: fmt
fmt: ## Format Golang codebase and "optimize" the dependencies
go fix -embedlit=false -errorsastype=false ./...
golangci-lint fmt
go mod tidy
.PHONY: prettify
prettify: ## Format non-Golang codebase
npx prettier --write .
# go install golang.org/x/tools/cmd/godoc@latest
.PHONY: godoc
godoc: ## Run a webserver with Gotenberg godoc
$(info http://localhost:6060/pkg/github.com/gotenberg/gotenberg/v8)
godoc -http=:6060