ifeq ($(USE_REPO_TEST_DIR),1) # This rule replaces the whole Makefile when we're trying to use /tmp repository temporary fileslocation = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))self := $(location) %: @tmpdir=`mktemp --tmpdir -d` ; \ echo Using temporary directory $$tmpdir for test repositories ; \ USE_REPO_TEST_DIR= $(MAKE) -f $(self) --no-print-directory REPO_TEST_DIR=$$tmpdir/ $@ ; \ STATUS=$$? ; rm -r "$$tmpdir" ; exit $$STATUS else # This is the "normal" part of the Makefile DIST := distDIST_DIRS := $(DIST)/binaries $(DIST)/releaseIMPORT := forgejo.org GO ?= $(shell go env GOROOT)/bin/goSHASUM ?= shasum -a 256HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes)COMMA := ,DIFF ?= diff --unified ifeq ($(USE_GOTESTSUM), yes) GOTEST ?= gotestsum -- GOTESTCOMPILEDRUNPREFIX ?= gotestsum --raw-command -- go tool test2json -t GOTESTCOMPILEDRUNSUFFIX ?= -test.v=test2jsonelse GOTEST ?= $(GO) test GOTESTCOMPILEDRUNPREFIX ?= GOTESTCOMPILEDRUNSUFFIX ?=endif XGO_VERSION := go-1.21.x AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=goEDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.3.0 # renovate: datasource=goGOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.8.0 # renovate: datasource=goGOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.3.1 # renovate: datasource=goGXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=goSWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 # renovate: datasource=goXGO_PACKAGE ?= src.techknowlogick.com/xgo@latestGO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasource=goGOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=goDEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.35.0 # renovate: datasource=goGOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.5.2 # renovate: datasource=goRENOVATE_NPM_PACKAGE ?= renovate@41.61.0 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... ifeq ($(HAS_GO), yes) CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766 CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS)endif GOFLAGS := -vEXECUTABLE ?= gitea ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu) SED_INPLACE := sed -ielse SED_INPLACE := sed -i ''endif EXTRA_GOFLAGS ?= MAKE_VERSION := $(shell "$(MAKE)" -v | cat | head -n 1)MAKE_EVIDENCE_DIR := .make_evidence ifeq ($(RACE_ENABLED),true) GOFLAGS += -race GOTESTFLAGS += -raceendif STORED_VERSION_FILE := VERSIONHUGO_VERSION ?= 0.111.3 GITEA_COMPATIBILITY ?= gitea-1.22.0 STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null)ifneq ($(STORED_VERSION),) FORGEJO_VERSION ?= $(STORED_VERSION)else ifneq ($(GITEA_VERSION),) FORGEJO_VERSION ?= $(GITEA_VERSION) FORGEJO_VERSION_API ?= $(GITEA_VERSION)+${GITEA_COMPATIBILITY} else # drop the "g" prefix prepended by git describe to the commit hash FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always 2>/dev/null | sed 's/^v//' | sed 's/\-g/-/') ifneq ($(FORGEJO_VERSION),) ifeq ($(findstring $(GITEA_COMPATIBILITY),$(FORGEJO_VERSION)),) FORGEJO_VERSION := $(FORGEJO_VERSION)+$(GITEA_COMPATIBILITY) endif endif endifendifFORGEJO_VERSION_MAJOR=$(shell echo $(FORGEJO_VERSION) | sed -e 's/\..*//')FORGEJO_VERSION_MINOR=$(shell echo $(FORGEJO_VERSION) | sed -E -e 's/^([0-9]+\.[0-9]+).*/\1/') RELEASE_VERSION ?= ${FORGEJO_VERSION}VERSION ?= ${RELEASE_VERSION} FORGEJO_VERSION_API ?= ${FORGEJO_VERSION} # Strip binaries by default to reduce size, allow overriding for debuggingSTRIP ?= 1ifeq ($(STRIP),1) LDFLAGS := $(LDFLAGS) -s -wendifLDFLAGS := $(LDFLAGS) -X "main.ReleaseVersion=$(RELEASE_VERSION)" -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(FORGEJO_VERSION)" -X "main.Tags=$(TAGS)" -X "main.ForgejoVersion=$(FORGEJO_VERSION_API)" LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64 ifeq ($(HAS_GO), yes) GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list forgejo.org/models/migrations/...) $(shell $(GO) list forgejo.org/models/forgejo_migrations/...) forgejo.org/tests/integration/migration-test forgejo.org/tests forgejo.org/tests/integration forgejo.org/tests/e2e,$(shell $(GO) list ./...))endifREMOTE_CACHER_MODULES ?= cache nosql session queueGO_TEST_REMOTE_CACHER_PACKAGES ?= $(addprefix forgejo.org/modules/,$(REMOTE_CACHER_MODULES)) FOMANTIC_WORK_DIR := web_src/fomantic WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)WEBPACK_CONFIGS := webpack.config.js tailwind.config.jsWEBPACK_DEST := public/assets/js/index.js public/assets/css/index.cssWEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts BINDATA_DEST := modules/migration/bindata.go modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.goBINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST)) GENERATED_GO_DEST := modules/charset/invisible_gen.go modules/charset/ambiguous_gen.go SVG_DEST_DIR := public/assets/img/svg AIR_TMP_DIR := .air GO_LICENSE_TMP_DIR := .go-licensesGO_LICENSE_FILE := assets/go-licenses.json TAGS ?=TAGS_SPLIT := $(subst $(COMMA), ,$(TAGS))TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags TEST_TAGS ?= sqlite sqlite_unlock_notify TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR) GO_DIRS := build cmd models modules routers services testsWEB_DIRS := web_src/js web_src/css STYLELINT_FILES := web_src/css web_src/js/components/*.vueSPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github $(wildcard *.go *.js *.ts *.vue *.md *.yml *.yaml) GO_SOURCES := $(wildcard *.go)GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" ! -path modules/options/bindata.go ! -path modules/public/bindata.go ! -path modules/templates/bindata.go)GO_SOURCES += $(GENERATED_GO_DEST)GO_SOURCES_NO_BINDATA := $(GO_SOURCES) ifeq ($(HAS_GO), yes) MIGRATION_PACKAGES := $(shell $(GO) list forgejo.org/models/migrations/... forgejo.org/models/forgejo_migrations/...)endif ifeq ($(filter $(TAGS_SPLIT),bindata),bindata) GO_SOURCES += $(BINDATA_DEST) GENERATED_GO_DEST += $(BINDATA_DEST)endif # Force installation of playwright dependencies by setting this flagifdef DEPS_PLAYWRIGHT PLAYWRIGHT_FLAGS += --with-depsendif FORGEJO_API_SPEC := public/assets/forgejo/api.v1.yml SWAGGER_SPEC := templates/swagger/v1_json.tmplSWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape}}/api/v1"|gSWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape}}/api/v1"|"basePath": "/api/v1"|gSWAGGER_EXCLUDE := code.gitea.io/sdkSWAGGER_NEWLINE_COMMAND := -e '$$a\'SWAGGER_SPEC_BRANDING := s|Gitea API|Forgejo API|gSWAGGER_SPEC_LICENSE := s|"name": "MIT"|"name": "This file is distributed under the MIT license for the purpose of interoperability"| TEST_MYSQL_HOST ?= mysql:3306TEST_MYSQL_DBNAME ?= testgitea?multiStatements=trueTEST_MYSQL_USERNAME ?= rootTEST_MYSQL_PASSWORD ?=TEST_PGSQL_HOST ?= pgsql:5432TEST_PGSQL_DBNAME ?= testgiteaTEST_PGSQL_USERNAME ?= postgresTEST_PGSQL_PASSWORD ?= postgresTEST_PGSQL_SCHEMA ?= gtestschema .PHONY: allall: build .PHONY: helphelp: @echo "Make Routines:" @echo " - \"\" equivalent to \"build\"" @echo " - build build everything" @echo " - frontend build frontend files" @echo " - backend build backend files" @echo " - watch watch everything and continuously rebuild" @echo " - watch-frontend watch frontend files and continuously rebuild" @echo " - watch-backend watch backend files and continuously rebuild" @echo " - clean delete backend and integration files" @echo " - clean-all delete backend, frontend and integration files" @echo " - deps install dependencies" @echo " - deps-frontend install frontend dependencies" @echo " - deps-backend install backend dependencies" @echo " - deps-tools install tool dependencies" @echo " - lint lint everything" @echo " - lint-fix lint everything and fix issues" @echo " - lint-frontend lint frontend files" @echo " - lint-frontend-fix lint frontend files and fix issues" @echo " - lint-backend lint backend files" @echo " - lint-backend-fix lint backend files and fix issues" @echo " - lint-go lint go files" @echo " - lint-go-fix lint go files and fix issues" @echo " - lint-go-vet lint go files with vet" @echo " - lint-js lint js files" @echo " - lint-js-fix lint js files and fix issues" @echo " - lint-css lint css files" @echo " - lint-css-fix lint css files and fix issues" @echo " - lint-md lint markdown files" @echo " - lint-swagger lint swagger files" @echo " - lint-renovate lint renovate files" @echo " - checks run various consistency checks" @echo " - checks-frontend check frontend files" @echo " - checks-backend check backend files" @echo " - test test everything" @echo " - show-version-full show the same version as the API endpoint" @echo " - show-version-major show major release number only" @echo " - test-frontend test frontend files" @echo " - test-frontend-coverage test frontend files and display code coverage" @echo " - test-backend test backend files" @echo " - test-remote-cacher test backend files that use a remote cache" @echo " - test-e2e-sqlite[\#name.test.e2e] test end to end using playwright and sqlite" @echo " - webpack build webpack files" @echo " - svg build svg files" @echo " - fomantic build fomantic files" @echo " - generate run \"go generate\"" @echo " - fmt format the Go code" @echo " - generate-license update license files" @echo " - generate-gitignore update gitignore files" @echo " - generate-manpage generate manpage" @echo " - generate-gomock generate gomock files" @echo " - generate-forgejo-api generate the forgejo API from spec" @echo " - forgejo-api-validate check if the forgejo API matches the specs" @echo " - generate-swagger generate the swagger spec from code comments" @echo " - swagger-validate check if the swagger spec is valid" @echo " - go-licenses regenerate go licenses" @echo " - tidy run go mod tidy" @echo " - test[\#TestSpecificName] run unit test" @echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite" @echo " - reproduce-build\#version build a reproducible binary for the specified release version" .PHONY: verify-versionverify-version:ifeq ($(FORGEJO_VERSION),) @echo "Error: Could not determine FORGEJO_VERSION; version file $(STORED_VERSION_FILE) not present and no suitable git tag found" @echo 'In most cases this likely means you forgot to fetch git tags, you can fix this by executing `git fetch --tags`. If this is not possible and this is part of a custom build process, then you can set a specific version by writing it to $(STORED_VERSION_FILE) (This must be a semver compatible version).' @falseendif .PHONY: show-version-fullshow-version-full: verify-version @echo ${FORGEJO_VERSION} .PHONY: show-version-majorshow-version-major: verify-version @echo ${FORGEJO_VERSION_MAJOR} .PHONY: show-version-minorshow-version-minor: verify-version @echo ${FORGEJO_VERSION_MINOR} .PHONY: show-version-apishow-version-api: verify-version @echo ${FORGEJO_VERSION_API} #### Check system and environment requirements### .PHONY: go-checkgo-check: $(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9]+' go.mod | cut -d' ' -f2)) $(eval MIN_GO_VERSION := $(shell printf "%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' '))) $(eval GO_VERSION := $(shell printf "%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9]+' | tr '.' ' ');)) @if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \ echo "Forgejo requires Go $(MIN_GO_VERSION_STR) or greater to build. You can get it at https://go.dev/dl/"; \ exit 1; \ fi .PHONY: git-checkgit-check: @if git lfs >/dev/null 2>&1 ; then : ; else \ echo "Forgejo requires git with lfs support to run tests." ; \ exit 1; \ fi .PHONY: node-checknode-check: $(eval MIN_NODE_VERSION_STR := $(shell grep -Eo '"node":.*[0-9.]+"' package.json | sed -n 's/.*[^0-9.]\([0-9.]*\)"/\1/p')) $(eval MIN_NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_NODE_VERSION_STR)' | tr '.' ' '))) $(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');)) $(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1)) @if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \ echo "Forgejo requires Node.js $(MIN_NODE_VERSION_STR) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \ exit 1; \ fi #### Basic maintenance, check and lint targets### .PHONY: clean-allclean-all: clean rm -rf $(WEBPACK_DEST_ENTRIES) node_modules .PHONY: cleanclean: clean-no-bindata rm -rf $(BINDATA_DEST) $(BINDATA_HASH) .PHONY: clean-no-bindataclean-no-bindata: rm -rf $(EXECUTABLE) $(DIST) \ integrations*.test \ e2e*.test \ tests/integration/gitea-integration-* \ tests/integration/indexers-* \ tests/mysql.ini tests/pgsql.ini man/ \ tests/e2e/gitea-e2e-*/ \ tests/e2e/indexers-*/ \ tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/ .PHONY: fmtfmt: @GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}' $(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl')) @# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only @# whitespace before it @$(SED_INPLACE) \ -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' \ -e 's/([ ]\{1,\}/(/g' -e '/^[ ]\{1,\})/! s/[ ]\{1,\})/)/g' \ $(TEMPLATES) .PHONY: fmt-checkfmt-check: fmt @git diff --exit-code --color=always $(GO_SOURCES) templates $(WEB_DIRS) \ || (code=$$?; echo "Please run 'make fmt' and commit the result"; exit $${code}) .PHONY: $(TAGS_EVIDENCE)$(TAGS_EVIDENCE): @mkdir -p $(MAKE_EVIDENCE_DIR) @echo "$(TAGS)" > $(TAGS_EVIDENCE) ifneq "$(TAGS)" "$(shell cat $(TAGS_EVIDENCE) 2>/dev/null)"TAGS_PREREQ := $(TAGS_EVIDENCE)endif OAPI_CODEGEN_PACKAGE ?= github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4KIN_OPENAPI_CODEGEN_PACKAGE ?= github.com/getkin/kin-openapi/cmd/validate@v0.114.0FORGEJO_API_SERVER = routers/api/forgejo/v1/generated.go .PHONY: generate-forgejo-apigenerate-forgejo-api: $(FORGEJO_API_SPEC) $(GO) run $(OAPI_CODEGEN_PACKAGE) -package v1 -generate chi-server,types $< > $(FORGEJO_API_SERVER) .PHONY: forgejo-api-checkforgejo-api-check: generate-forgejo-api @git diff --exit-code --color=always $(FORGEJO_API_SERVER) \ || (code=$$?; echo "Please run 'make generate-forgejo-api' and commit the result"; exit $${code}) .PHONY: forgejo-api-validateforgejo-api-validate: $(GO) run $(KIN_OPENAPI_CODEGEN_PACKAGE) $(FORGEJO_API_SPEC) .PHONY: generate-swaggergenerate-swagger: $(SWAGGER_SPEC) $(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA) $(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_BRANDING)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_LICENSE)' './$(SWAGGER_SPEC)' .PHONY: swagger-checkswagger-check: generate-swagger @git diff --exit-code --color=always '$(SWAGGER_SPEC)' \ || (code=$$?; echo "Please run 'make generate-swagger' and commit the result"; exit $${code}) .PHONY: swagger-validateswagger-validate: $(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)' $(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' .PHONY: checkschecks: checks-frontend checks-backend .PHONY: checks-frontendchecks-frontend: lockfile-check svg-check .PHONY: checks-backendchecks-backend: tidy-check swagger-check fmt-check swagger-validate security-check .PHONY: lintlint: lint-frontend lint-backend .PHONY: lint-fixlint-fix: lint-frontend-fix lint-backend-fix .PHONY: lint-frontendlint-frontend: lint-js lint-css .PHONY: lint-frontend-fixlint-frontend-fix: lint-js-fix lint-css-fix .PHONY: lint-backendlint-backend: lint-go lint-go-vet lint-editorconfig lint-renovate lint-locale lint-locale-usage lint-disposable-emails .PHONY: lint-backend-fixlint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig lint-disposable-emails-fix .PHONY: lint-jslint-js: node_modules npx eslint --color --max-warnings=0 .PHONY: lint-js-fixlint-js-fix: node_modules npx eslint --color --max-warnings=0 --fix .PHONY: lint-csslint-css: node_modules npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) .PHONY: lint-css-fixlint-css-fix: node_modules npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix .PHONY: lint-swaggerlint-swagger: node_modules npx spectral lint -q -F hint $(SWAGGER_SPEC) .PHONY: lint-renovatelint-renovate: node_modules npx --yes --package $(RENOVATE_NPM_PACKAGE) -- renovate-config-validator > .lint-renovate 2>&1 || true @if grep --quiet --extended-regexp -e '^( ERROR:)' .lint-renovate ; then cat .lint-renovate ; rm .lint-renovate ; exit 1 ; fi @rm .lint-renovate .PHONY: lint-localelint-locale: $(GO) run build/lint-locale/lint-locale.go .PHONY: lint-locale-usagelint-locale-usage: $(GO) run build/lint-locale-usage/lint-locale-usage.go .PHONY: lint-mdlint-md: node_modules npx markdownlint docs *.md RUN_DEADCODE = $(GO) run $(DEADCODE_PACKAGE) -generated=false -f='{{println .Path}}{{range .Funcs}}{{printf "\t%s\n" .Name}}{{end}}{{println}}' -test forgejo.org .PHONY: lint-golint-go: $(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) $(RUN_DEADCODE) > .cur-deadcode-out @$(DIFF) .deadcode-out .cur-deadcode-out \ || (code=$$?; echo "Please run 'make lint-go-fix' and commit the result"; exit $${code}) .PHONY: lint-go-fixlint-go-fix: $(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) --fix $(RUN_DEADCODE) > .deadcode-out .PHONY: lint-go-vetlint-go-vet: @echo "Running go vet..." @$(GO) vet ./... .PHONY: lint-editorconfiglint-editorconfig: $(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .forgejo/workflows .PHONY: lint-disposable-emailslint-disposable-emails: $(GO) run build/generate-disposable-email.go -check -r $(DISPOSABLE_EMAILS_SHA) .PHONY: lint-disposable-emails-fixlint-disposable-emails-fix: $(GO) run build/generate-disposable-email.go -r $(DISPOSABLE_EMAILS_SHA) .PHONY: security-checkLines 1–500 of 1008. Load more
ifeq ($(USE_REPO_TEST_DIR),1) # This rule replaces the whole Makefile when we're trying to use /tmp repository temporary files location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) self := $(location) %: @tmpdir=`mktemp --tmpdir -d` ; \ echo Using temporary directory $$tmpdir for test repositories ; \ USE_REPO_TEST_DIR= $(MAKE) -f $(self) --no-print-directory REPO_TEST_DIR=$$tmpdir/ $@ ; \ STATUS=$$? ; rm -r "$$tmpdir" ; exit $$STATUS else # This is the "normal" part of the Makefile DIST := dist DIST_DIRS := $(DIST)/binaries $(DIST)/release IMPORT := forgejo.org GO ?= $(shell go env GOROOT)/bin/go SHASUM ?= shasum -a 256 HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes) COMMA := , DIFF ?= diff --unified ifeq ($(USE_GOTESTSUM), yes) GOTEST ?= gotestsum -- GOTESTCOMPILEDRUNPREFIX ?= gotestsum --raw-command -- go tool test2json -t GOTESTCOMPILEDRUNSUFFIX ?= -test.v=test2json else GOTEST ?= $(GO) test GOTESTCOMPILEDRUNPREFIX ?= GOTESTCOMPILEDRUNSUFFIX ?= endif XGO_VERSION := go-1.21.x AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.3.0 # renovate: datasource=go GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.8.0 # renovate: datasource=go GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.3.1 # renovate: datasource=go GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 # renovate: datasource=go XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasource=go GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.35.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.5.2 # renovate: datasource=go RENOVATE_NPM_PACKAGE ?= renovate@41.61.0 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/ DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... ifeq ($(HAS_GO), yes) CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766 CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS) endif GOFLAGS := -v EXECUTABLE ?= gitea ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu) SED_INPLACE := sed -i else SED_INPLACE := sed -i '' endif EXTRA_GOFLAGS ?= MAKE_VERSION := $(shell "$(MAKE)" -v | cat | head -n 1) MAKE_EVIDENCE_DIR := .make_evidence ifeq ($(RACE_ENABLED),true) GOFLAGS += -race GOTESTFLAGS += -race endif STORED_VERSION_FILE := VERSION HUGO_VERSION ?= 0.111.3 GITEA_COMPATIBILITY ?= gitea-1.22.0 STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null) ifneq ($(STORED_VERSION),) FORGEJO_VERSION ?= $(STORED_VERSION) else ifneq ($(GITEA_VERSION),) FORGEJO_VERSION ?= $(GITEA_VERSION) FORGEJO_VERSION_API ?= $(GITEA_VERSION)+${GITEA_COMPATIBILITY} else # drop the "g" prefix prepended by git describe to the commit hash FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always 2>/dev/null | sed 's/^v//' | sed 's/\-g/-/') ifneq ($(FORGEJO_VERSION),) ifeq ($(findstring $(GITEA_COMPATIBILITY),$(FORGEJO_VERSION)),) FORGEJO_VERSION := $(FORGEJO_VERSION)+$(GITEA_COMPATIBILITY) endif endif endif endif FORGEJO_VERSION_MAJOR=$(shell echo $(FORGEJO_VERSION) | sed -e 's/\..*//') FORGEJO_VERSION_MINOR=$(shell echo $(FORGEJO_VERSION) | sed -E -e 's/^([0-9]+\.[0-9]+).*/\1/') RELEASE_VERSION ?= ${FORGEJO_VERSION} VERSION ?= ${RELEASE_VERSION} FORGEJO_VERSION_API ?= ${FORGEJO_VERSION} # Strip binaries by default to reduce size, allow overriding for debugging STRIP ?= 1 ifeq ($(STRIP),1) LDFLAGS := $(LDFLAGS) -s -w endif LDFLAGS := $(LDFLAGS) -X "main.ReleaseVersion=$(RELEASE_VERSION)" -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(FORGEJO_VERSION)" -X "main.Tags=$(TAGS)" -X "main.ForgejoVersion=$(FORGEJO_VERSION_API)" LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64 ifeq ($(HAS_GO), yes) GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list forgejo.org/models/migrations/...) $(shell $(GO) list forgejo.org/models/forgejo_migrations/...) forgejo.org/tests/integration/migration-test forgejo.org/tests forgejo.org/tests/integration forgejo.org/tests/e2e,$(shell $(GO) list ./...)) endif REMOTE_CACHER_MODULES ?= cache nosql session queue GO_TEST_REMOTE_CACHER_PACKAGES ?= $(addprefix forgejo.org/modules/,$(REMOTE_CACHER_MODULES)) FOMANTIC_WORK_DIR := web_src/fomantic WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f) WEBPACK_CONFIGS := webpack.config.js tailwind.config.js WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts BINDATA_DEST := modules/migration/bindata.go modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST)) GENERATED_GO_DEST := modules/charset/invisible_gen.go modules/charset/ambiguous_gen.go SVG_DEST_DIR := public/assets/img/svg AIR_TMP_DIR := .air GO_LICENSE_TMP_DIR := .go-licenses GO_LICENSE_FILE := assets/go-licenses.json TAGS ?= TAGS_SPLIT := $(subst $(COMMA), ,$(TAGS)) TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags TEST_TAGS ?= sqlite sqlite_unlock_notify TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR) $(GO_LICENSE_TMP_DIR) GO_DIRS := build cmd models modules routers services tests WEB_DIRS := web_src/js web_src/css STYLELINT_FILES := web_src/css web_src/js/components/*.vue SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github $(wildcard *.go *.js *.ts *.vue *.md *.yml *.yaml) GO_SOURCES := $(wildcard *.go) GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" ! -path modules/options/bindata.go ! -path modules/public/bindata.go ! -path modules/templates/bindata.go) GO_SOURCES += $(GENERATED_GO_DEST) GO_SOURCES_NO_BINDATA := $(GO_SOURCES) ifeq ($(HAS_GO), yes) MIGRATION_PACKAGES := $(shell $(GO) list forgejo.org/models/migrations/... forgejo.org/models/forgejo_migrations/...) endif ifeq ($(filter $(TAGS_SPLIT),bindata),bindata) GO_SOURCES += $(BINDATA_DEST) GENERATED_GO_DEST += $(BINDATA_DEST) endif # Force installation of playwright dependencies by setting this flag ifdef DEPS_PLAYWRIGHT PLAYWRIGHT_FLAGS += --with-deps endif FORGEJO_API_SPEC := public/assets/forgejo/api.v1.yml SWAGGER_SPEC := templates/swagger/v1_json.tmpl SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape}}/api/v1"|g SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape}}/api/v1"|"basePath": "/api/v1"|g SWAGGER_EXCLUDE := code.gitea.io/sdk SWAGGER_NEWLINE_COMMAND := -e '$$a\' SWAGGER_SPEC_BRANDING := s|Gitea API|Forgejo API|g SWAGGER_SPEC_LICENSE := s|"name": "MIT"|"name": "This file is distributed under the MIT license for the purpose of interoperability"| TEST_MYSQL_HOST ?= mysql:3306 TEST_MYSQL_DBNAME ?= testgitea?multiStatements=true TEST_MYSQL_USERNAME ?= root TEST_MYSQL_PASSWORD ?= TEST_PGSQL_HOST ?= pgsql:5432 TEST_PGSQL_DBNAME ?= testgitea TEST_PGSQL_USERNAME ?= postgres TEST_PGSQL_PASSWORD ?= postgres TEST_PGSQL_SCHEMA ?= gtestschema .PHONY: all all: build .PHONY: help help: @echo "Make Routines:" @echo " - \"\" equivalent to \"build\"" @echo " - build build everything" @echo " - frontend build frontend files" @echo " - backend build backend files" @echo " - watch watch everything and continuously rebuild" @echo " - watch-frontend watch frontend files and continuously rebuild" @echo " - watch-backend watch backend files and continuously rebuild" @echo " - clean delete backend and integration files" @echo " - clean-all delete backend, frontend and integration files" @echo " - deps install dependencies" @echo " - deps-frontend install frontend dependencies" @echo " - deps-backend install backend dependencies" @echo " - deps-tools install tool dependencies" @echo " - lint lint everything" @echo " - lint-fix lint everything and fix issues" @echo " - lint-frontend lint frontend files" @echo " - lint-frontend-fix lint frontend files and fix issues" @echo " - lint-backend lint backend files" @echo " - lint-backend-fix lint backend files and fix issues" @echo " - lint-go lint go files" @echo " - lint-go-fix lint go files and fix issues" @echo " - lint-go-vet lint go files with vet" @echo " - lint-js lint js files" @echo " - lint-js-fix lint js files and fix issues" @echo " - lint-css lint css files" @echo " - lint-css-fix lint css files and fix issues" @echo " - lint-md lint markdown files" @echo " - lint-swagger lint swagger files" @echo " - lint-renovate lint renovate files" @echo " - checks run various consistency checks" @echo " - checks-frontend check frontend files" @echo " - checks-backend check backend files" @echo " - test test everything" @echo " - show-version-full show the same version as the API endpoint" @echo " - show-version-major show major release number only" @echo " - test-frontend test frontend files" @echo " - test-frontend-coverage test frontend files and display code coverage" @echo " - test-backend test backend files" @echo " - test-remote-cacher test backend files that use a remote cache" @echo " - test-e2e-sqlite[\#name.test.e2e] test end to end using playwright and sqlite" @echo " - webpack build webpack files" @echo " - svg build svg files" @echo " - fomantic build fomantic files" @echo " - generate run \"go generate\"" @echo " - fmt format the Go code" @echo " - generate-license update license files" @echo " - generate-gitignore update gitignore files" @echo " - generate-manpage generate manpage" @echo " - generate-gomock generate gomock files" @echo " - generate-forgejo-api generate the forgejo API from spec" @echo " - forgejo-api-validate check if the forgejo API matches the specs" @echo " - generate-swagger generate the swagger spec from code comments" @echo " - swagger-validate check if the swagger spec is valid" @echo " - go-licenses regenerate go licenses" @echo " - tidy run go mod tidy" @echo " - test[\#TestSpecificName] run unit test" @echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite" @echo " - reproduce-build\#version build a reproducible binary for the specified release version" .PHONY: verify-version verify-version: ifeq ($(FORGEJO_VERSION),) @echo "Error: Could not determine FORGEJO_VERSION; version file $(STORED_VERSION_FILE) not present and no suitable git tag found" @echo 'In most cases this likely means you forgot to fetch git tags, you can fix this by executing `git fetch --tags`. If this is not possible and this is part of a custom build process, then you can set a specific version by writing it to $(STORED_VERSION_FILE) (This must be a semver compatible version).' @false endif .PHONY: show-version-full show-version-full: verify-version @echo ${FORGEJO_VERSION} .PHONY: show-version-major show-version-major: verify-version @echo ${FORGEJO_VERSION_MAJOR} .PHONY: show-version-minor show-version-minor: verify-version @echo ${FORGEJO_VERSION_MINOR} .PHONY: show-version-api show-version-api: verify-version @echo ${FORGEJO_VERSION_API} ### # Check system and environment requirements ### .PHONY: go-check go-check: $(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9]+' go.mod | cut -d' ' -f2)) $(eval MIN_GO_VERSION := $(shell printf "%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' '))) $(eval GO_VERSION := $(shell printf "%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9]+' | tr '.' ' ');)) @if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \ echo "Forgejo requires Go $(MIN_GO_VERSION_STR) or greater to build. You can get it at https://go.dev/dl/"; \ exit 1; \ fi .PHONY: git-check git-check: @if git lfs >/dev/null 2>&1 ; then : ; else \ echo "Forgejo requires git with lfs support to run tests." ; \ exit 1; \ fi .PHONY: node-check node-check: $(eval MIN_NODE_VERSION_STR := $(shell grep -Eo '"node":.*[0-9.]+"' package.json | sed -n 's/.*[^0-9.]\([0-9.]*\)"/\1/p')) $(eval MIN_NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_NODE_VERSION_STR)' | tr '.' ' '))) $(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');)) $(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1)) @if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \ echo "Forgejo requires Node.js $(MIN_NODE_VERSION_STR) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \ exit 1; \ fi ### # Basic maintenance, check and lint targets ### .PHONY: clean-all clean-all: clean rm -rf $(WEBPACK_DEST_ENTRIES) node_modules .PHONY: clean clean: clean-no-bindata rm -rf $(BINDATA_DEST) $(BINDATA_HASH) .PHONY: clean-no-bindata clean-no-bindata: rm -rf $(EXECUTABLE) $(DIST) \ integrations*.test \ e2e*.test \ tests/integration/gitea-integration-* \ tests/integration/indexers-* \ tests/mysql.ini tests/pgsql.ini man/ \ tests/e2e/gitea-e2e-*/ \ tests/e2e/indexers-*/ \ tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/ .PHONY: fmt fmt: @GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}' $(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl')) @# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only @# whitespace before it @$(SED_INPLACE) \ -e 's/{{[ ]\{1,\}/{{/g' -e '/^[ ]\{1,\}}}/! s/[ ]\{1,\}}}/}}/g' \ -e 's/([ ]\{1,\}/(/g' -e '/^[ ]\{1,\})/! s/[ ]\{1,\})/)/g' \ $(TEMPLATES) .PHONY: fmt-check fmt-check: fmt @git diff --exit-code --color=always $(GO_SOURCES) templates $(WEB_DIRS) \ || (code=$$?; echo "Please run 'make fmt' and commit the result"; exit $${code}) .PHONY: $(TAGS_EVIDENCE) $(TAGS_EVIDENCE): @mkdir -p $(MAKE_EVIDENCE_DIR) @echo "$(TAGS)" > $(TAGS_EVIDENCE) ifneq "$(TAGS)" "$(shell cat $(TAGS_EVIDENCE) 2>/dev/null)" TAGS_PREREQ := $(TAGS_EVIDENCE) endif OAPI_CODEGEN_PACKAGE ?= github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 KIN_OPENAPI_CODEGEN_PACKAGE ?= github.com/getkin/kin-openapi/cmd/validate@v0.114.0 FORGEJO_API_SERVER = routers/api/forgejo/v1/generated.go .PHONY: generate-forgejo-api generate-forgejo-api: $(FORGEJO_API_SPEC) $(GO) run $(OAPI_CODEGEN_PACKAGE) -package v1 -generate chi-server,types $< > $(FORGEJO_API_SERVER) .PHONY: forgejo-api-check forgejo-api-check: generate-forgejo-api @git diff --exit-code --color=always $(FORGEJO_API_SERVER) \ || (code=$$?; echo "Please run 'make generate-forgejo-api' and commit the result"; exit $${code}) .PHONY: forgejo-api-validate forgejo-api-validate: $(GO) run $(KIN_OPENAPI_CODEGEN_PACKAGE) $(FORGEJO_API_SPEC) .PHONY: generate-swagger generate-swagger: $(SWAGGER_SPEC) $(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA) $(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' $(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_BRANDING)' './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_LICENSE)' './$(SWAGGER_SPEC)' .PHONY: swagger-check swagger-check: generate-swagger @git diff --exit-code --color=always '$(SWAGGER_SPEC)' \ || (code=$$?; echo "Please run 'make generate-swagger' and commit the result"; exit $${code}) .PHONY: swagger-validate swagger-validate: $(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)' $(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' .PHONY: checks checks: checks-frontend checks-backend .PHONY: checks-frontend checks-frontend: lockfile-check svg-check .PHONY: checks-backend checks-backend: tidy-check swagger-check fmt-check swagger-validate security-check .PHONY: lint lint: lint-frontend lint-backend .PHONY: lint-fix lint-fix: lint-frontend-fix lint-backend-fix .PHONY: lint-frontend lint-frontend: lint-js lint-css .PHONY: lint-frontend-fix lint-frontend-fix: lint-js-fix lint-css-fix .PHONY: lint-backend lint-backend: lint-go lint-go-vet lint-editorconfig lint-renovate lint-locale lint-locale-usage lint-disposable-emails .PHONY: lint-backend-fix lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig lint-disposable-emails-fix .PHONY: lint-js lint-js: node_modules npx eslint --color --max-warnings=0 .PHONY: lint-js-fix lint-js-fix: node_modules npx eslint --color --max-warnings=0 --fix .PHONY: lint-css lint-css: node_modules npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) .PHONY: lint-css-fix lint-css-fix: node_modules npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix .PHONY: lint-swagger lint-swagger: node_modules npx spectral lint -q -F hint $(SWAGGER_SPEC) .PHONY: lint-renovate lint-renovate: node_modules npx --yes --package $(RENOVATE_NPM_PACKAGE) -- renovate-config-validator > .lint-renovate 2>&1 || true @if grep --quiet --extended-regexp -e '^( ERROR:)' .lint-renovate ; then cat .lint-renovate ; rm .lint-renovate ; exit 1 ; fi @rm .lint-renovate .PHONY: lint-locale lint-locale: $(GO) run build/lint-locale/lint-locale.go .PHONY: lint-locale-usage lint-locale-usage: $(GO) run build/lint-locale-usage/lint-locale-usage.go .PHONY: lint-md lint-md: node_modules npx markdownlint docs *.md RUN_DEADCODE = $(GO) run $(DEADCODE_PACKAGE) -generated=false -f='{{println .Path}}{{range .Funcs}}{{printf "\t%s\n" .Name}}{{end}}{{println}}' -test forgejo.org .PHONY: lint-go lint-go: $(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) $(RUN_DEADCODE) > .cur-deadcode-out @$(DIFF) .deadcode-out .cur-deadcode-out \ || (code=$$?; echo "Please run 'make lint-go-fix' and commit the result"; exit $${code}) .PHONY: lint-go-fix lint-go-fix: $(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) --fix $(RUN_DEADCODE) > .deadcode-out .PHONY: lint-go-vet lint-go-vet: @echo "Running go vet..." @$(GO) vet ./... .PHONY: lint-editorconfig lint-editorconfig: $(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .forgejo/workflows .PHONY: lint-disposable-emails lint-disposable-emails: $(GO) run build/generate-disposable-email.go -check -r $(DISPOSABLE_EMAILS_SHA) .PHONY: lint-disposable-emails-fix lint-disposable-emails-fix: $(GO) run build/generate-disposable-email.go -r $(DISPOSABLE_EMAILS_SHA) .PHONY: security-check