CMakeLists.txt
Rama main · réplica de lectura del repositorio original.
cmake_minimum_required(VERSION 3.23)
option(BUILD_SIMPLE_ICONS "Embed simple-icons into the final binary, used for providing icons for transactions." ON)
option(BUILD_NOSIMD "Disable SIMD support at compile time." OFF)
option(BUILD_CONTAINER_TAG_LATEST "Tag containers with latest when building them." ON)
option(SIGN_RECURSIVE "Sign all referenced images recursively (covers each platform image of multi-arch builds)." OFF)
option(SIGN_TLOG_UPLOAD "Upload cosign signatures to the Sigstore Rekor transparency log." ON)
set(SIGN_CERT_IDENTITY_REGEX "^https://github.com/monetr/monetr/" CACHE STRING "OIDC certificate identity regex used to verify cosign signatures.")
set(SIGN_OIDC_ISSUER "https://token.actions.githubusercontent.com" CACHE STRING "OIDC issuer URL used to verify cosign signatures.")
option(TEST_RACE "Go tests should be run with the -race flag" ON)
option(TEST_COVERAGE "Coverage data should be collected from tests" ON)
option(TEST_USE_GOTESTSUM "Wrap test execution in gotestsum" OFF)
option(TEST_SHORT "Exclude long running tests" ON)
if (CMAKE_BUILD_TYPE STREQUAL "Release")
message(STATUS "Mode: Release")
else()
message(STATUS "Mode: Debug")
endif()
# This makes it possible to support some other languages.
# You'll find here we have the FindX files as well as some other ones.
# This will make it so cmake looks here for some Find files.
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
project(monetr Go)
# Get the hostname for the build.
if (WIN32)
set(HOME $ENV{USERPROFILE})
execute_process(COMMAND hostname OUTPUT_VARIABLE HOSTNAME OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
set(HOME $ENV{HOME})
execute_process(COMMAND uname -n OUTPUT_VARIABLE HOSTNAME OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
# monetr requires cgo in order to be built at this time, so if gcc is not present on the system then show a warning.
find_package(Gcc REQUIRED)
find_package(Git REQUIRED)
set(DOCKER_MIN_VERSION "26.0.0")
find_package(Docker QUIET)
find_program(COSIGN_EXECUTABLE cosign)
set(MONETR_PKG_ROOT github.com/monetr/monetr CACHE INTERNAL "Base go package for monetr.")
# The UI tasks are split out into their own file.
# Import this _after_ we have found all the packages above.
include(NodeModules)
include(GolangUtils)
add_subdirectory("${CMAKE_SOURCE_DIR}/images")
add_subdirectory("${CMAKE_SOURCE_DIR}/interface")
add_subdirectory("${CMAKE_SOURCE_DIR}/emails")
add_custom_target(
dependencies
DEPENDS dependencies.node_modules ${GO_MODULES}
)
if(DOCKER_EXECUTABLE)
message(STATUS "Container engine: Docker")
message(STATUS " Container build targets will be enabled!")
include("${CMAKE_SOURCE_DIR}/cmake/development.cmake")
if(NOT BUILD_PLATFORMS)
set(BUILD_PLATFORMS "linux/amd64,linux/arm64")
endif()
message(STATUS " Container will be built for platforms: ${BUILD_PLATFORMS}")
if(NOT "$ENV{CONTAINER_REGISTRY}" STREQUAL "")
set(CONTAINER_REGISTRY "$ENV{CONTAINER_REGISTRY}")
else()
set(CONTAINER_REGISTRY "ghcr.io/monetr/monetr" "docker.io/monetr/monetr" "quay.io/monetr/monetr")
endif()
set(CONTAINER_TAGS "$(CONTAINER_VERSION)")
if(BUILD_CONTAINER_TAG_LATEST)
list(APPEND CONTAINER_TAGS "latest")
endif()
set(CONTAINER_ARGS)
foreach(REGISTRY ${CONTAINER_REGISTRY})
foreach(TAG ${CONTAINER_TAGS})
list(APPEND CONTAINER_ARGS "-t" "${REGISTRY}:${TAG}")
endforeach()
endforeach()
set(DOCKER_CONTAINER ${CMAKE_BINARY_DIR}/docker-build-manifest.json)
add_custom_command(
OUTPUT ${DOCKER_CONTAINER}
BYPRODUCTS ${DOCKER_CONTAINER}
COMMENT "Building monetr container image"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS
${APP_GO_FILES}
${APP_UI_FILES}
${CMAKE_SOURCE_DIR}/Dockerfile
${CMAKE_SOURCE_DIR}/package.json
${CMAKE_SOURCE_DIR}/pnpm-lock.yaml
${PUBLIC_FILES}
${UI_CONFIG_FILES}
VERBATIM
COMMAND ${CMAKE_COMMAND} -E echo "-- Building monetr container: ${CONTAINER_REGISTRY} - ${CONTAINER_TAGS}"
COMMAND ${DOCKER_EXECUTABLE} buildx build
-f ${CMAKE_SOURCE_DIR}/Dockerfile
--platform ${BUILD_PLATFORMS}
--build-arg GOFLAGS=-tags=icons,simple_icons
--build-arg RELEASE=$(RELEASE_VERSION)
--build-arg REVISION=$(RELEASE_REVISION)
--build-arg BUILD_HOST=${HOSTNAME}
--metadata-file ${DOCKER_CONTAINER}
--label "index:org.opencontainers.image.url=https://monetr.app"
--label "index:org.opencontainers.image.source=https://github.com/monetr/monetr"
--label "index:org.opencontainers.image.authors=elliot.courant@monetr.app"
--label "index:org.opencontainers.image.vendor=monetr"
--label "index:org.opencontainers.image.licenses=FSL-1.1-MIT"
--label "index:org.opencontainers.image.description=monetr's budgeting application"
--label "index:org.opencontainers.image.version=$(RELEASE_VERSION)"
--label "index:org.opencontainers.image.revision=$(RELEASE_REVISION)"
--annotation "index:org.opencontainers.image.url=https://monetr.app"
--annotation "index:org.opencontainers.image.source=https://github.com/monetr/monetr"
--annotation "index:org.opencontainers.image.authors=elliot.courant@monetr.app"
--annotation "index:org.opencontainers.image.vendor=monetr"
--annotation "index:org.opencontainers.image.licenses=FSL-1.1-MIT"
--annotation "index:org.opencontainers.image.description=monetr's budgeting application"
--annotation "index:org.opencontainers.image.version=$(RELEASE_VERSION)"
--annotation "index:org.opencontainers.image.revision=$(RELEASE_REVISION)"
${CONTAINER_ARGS}
${CMAKE_SOURCE_DIR}
)
add_custom_target(
build.container.docker
DEPENDS ${DOCKER_CONTAINER}
)
set(DOCKER_CONTAINER_PUSH ${CMAKE_BINARY_DIR}/docker-container-push-manifest.json)
add_custom_command(
OUTPUT ${DOCKER_CONTAINER_PUSH}
BYPRODUCTS ${DOCKER_CONTAINER_PUSH}
COMMENT "Building monetr container image"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS
${APP_GO_FILES}
${APP_UI_FILES}
${CMAKE_SOURCE_DIR}/Dockerfile
${CMAKE_SOURCE_DIR}/package.json
${CMAKE_SOURCE_DIR}/pnpm-lock.yaml
${PUBLIC_FILES}
${UI_CONFIG_FILES}
VERBATIM
COMMAND ${CMAKE_COMMAND} -E echo "-- Building monetr container: ${CONTAINER_REGISTRY} - ${CONTAINER_TAGS}"
COMMAND ${DOCKER_EXECUTABLE} buildx build
--push
-f ${CMAKE_SOURCE_DIR}/Dockerfile
--platform ${BUILD_PLATFORMS}
--build-arg GOFLAGS=-tags=icons,simple_icons
--build-arg RELEASE=$(RELEASE_VERSION)
--build-arg REVISION=$(RELEASE_REVISION)
--build-arg BUILD_HOST=${HOSTNAME}
--metadata-file ${DOCKER_CONTAINER_PUSH}
--label "index:org.opencontainers.image.url=https://monetr.app"
--label "index:org.opencontainers.image.source=https://github.com/monetr/monetr"
--label "index:org.opencontainers.image.authors=elliot.courant@monetr.app"
--label "index:org.opencontainers.image.vendor=monetr"
--label "index:org.opencontainers.image.licenses=FSL-1.1-MIT"
--label "index:org.opencontainers.image.description=monetr's budgeting application"
--label "index:org.opencontainers.image.version=$(RELEASE_VERSION)"
--label "index:org.opencontainers.image.revision=$(RELEASE_REVISION)"
--annotation "index:org.opencontainers.image.url=https://monetr.app"
--annotation "index:org.opencontainers.image.source=https://github.com/monetr/monetr"
--annotation "index:org.opencontainers.image.authors=elliot.courant@monetr.app"
--annotation "index:org.opencontainers.image.vendor=monetr"
--annotation "index:org.opencontainers.image.licenses=FSL-1.1-MIT"
--annotation "index:org.opencontainers.image.description=monetr's budgeting application"
--annotation "index:org.opencontainers.image.version=$(RELEASE_VERSION)"
--annotation "index:org.opencontainers.image.revision=$(RELEASE_REVISION)"
${CONTAINER_ARGS}
${CMAKE_SOURCE_DIR}
)
add_custom_target(
build.container.docker.push
DEPENDS ${DOCKER_CONTAINER_PUSH}
)
if(COSIGN_EXECUTABLE)
message(STATUS " Container signing engine: cosign (${COSIGN_EXECUTABLE})")
# CMake's add_custom_command(COMMAND ...) splits list-valued args on the
# ; separator, which would expand a multi-registry list into separate
# cmake -P arguments. Join into a comma-separated string so the script
# gets a single -DREGISTRIES=... arg and re-splits on , at runtime.
list(JOIN CONTAINER_REGISTRY "," CONTAINER_REGISTRY_CSV)
set(DOCKER_CONTAINER_DIGEST ${CMAKE_BINARY_DIR}/docker-container-push.digest)
set(DOCKER_CONTAINER_SIGNING_CONFIG ${CMAKE_BINARY_DIR}/cosign-signing-config-no-tlog.json)
set(DOCKER_CONTAINER_SIGN_STAMP ${CMAKE_BINARY_DIR}/docker-container-sign.stamp)
add_custom_command(
OUTPUT ${DOCKER_CONTAINER_SIGN_STAMP}
BYPRODUCTS ${DOCKER_CONTAINER_SIGN_STAMP} ${DOCKER_CONTAINER_DIGEST} ${DOCKER_CONTAINER_SIGNING_CONFIG}
COMMENT "Signing monetr container images with cosign"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${DOCKER_CONTAINER_PUSH}
VERBATIM
COMMAND ${CMAKE_COMMAND}
"-DMETADATA_FILE=${DOCKER_CONTAINER_PUSH}"
"-DREGISTRIES=${CONTAINER_REGISTRY_CSV}"
"-DCOSIGN_EXECUTABLE=${COSIGN_EXECUTABLE}"
"-DSIGN_RECURSIVE=${SIGN_RECURSIVE}"
"-DSIGN_TLOG_UPLOAD=${SIGN_TLOG_UPLOAD}"
"-DDIGEST_FILE=${DOCKER_CONTAINER_DIGEST}"
"-DSIGNING_CONFIG_FILE=${DOCKER_CONTAINER_SIGNING_CONFIG}"
-P ${CMAKE_SOURCE_DIR}/cmake/scripts/CosignSign.cmake
COMMAND ${CMAKE_COMMAND} -E touch ${DOCKER_CONTAINER_SIGN_STAMP}
)
add_custom_target(
build.container.docker.sign
DEPENDS ${DOCKER_CONTAINER_SIGN_STAMP}
)
set(DOCKER_CONTAINER_VERIFY_STAMP ${CMAKE_BINARY_DIR}/docker-container-verify.stamp)
add_custom_command(
OUTPUT ${DOCKER_CONTAINER_VERIFY_STAMP}
BYPRODUCTS ${DOCKER_CONTAINER_VERIFY_STAMP}
COMMENT "Verifying monetr container image signatures with cosign"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${DOCKER_CONTAINER_SIGN_STAMP}
VERBATIM
COMMAND ${CMAKE_COMMAND}
"-DMETADATA_FILE=${DOCKER_CONTAINER_PUSH}"
"-DREGISTRIES=${CONTAINER_REGISTRY_CSV}"
"-DCOSIGN_EXECUTABLE=${COSIGN_EXECUTABLE}"
"-DSIGN_TLOG_UPLOAD=${SIGN_TLOG_UPLOAD}"
"-DSIGN_CERT_IDENTITY_REGEX=${SIGN_CERT_IDENTITY_REGEX}"
"-DSIGN_OIDC_ISSUER=${SIGN_OIDC_ISSUER}"
-P ${CMAKE_SOURCE_DIR}/cmake/scripts/CosignVerify.cmake
COMMAND ${CMAKE_COMMAND} -E touch ${DOCKER_CONTAINER_VERIFY_STAMP}
)
add_custom_target(
build.container.docker.verify
DEPENDS ${DOCKER_CONTAINER_VERIFY_STAMP}
)
else()
message(STATUS " cosign not found; container signing targets will be unavailable")
endif()
endif()
if(NOT DEFINED ENV{CI})
add_custom_target(lint
COMMENT "Linting monetr code base..."
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS tools.biome
COMMAND ${CMAKE_Go_COMPILER} fmt ./...
# Check all of the files that have changed since this commit, this is when the linting was introduced.
COMMAND ${BIOME_EXECUTABLE} check --write --max-diagnostics=1000 --since=6173df2df49e0754f0a2b902a433c712e034e1e2 --changed
)
else()
add_custom_target(lint
COMMENT "Linting monetr code base..."
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS tools.biome
# Check all of the files that have changed since this commit, this is when the linting was introduced.
COMMAND ${BIOME_EXECUTABLE} ci --reporter=github --max-diagnostics=1000 --since=6173df2df49e0754f0a2b902a433c712e034e1e2 --changed
)
endif()
add_custom_target(lint-all
COMMENT "Linting monetr code base..."
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS tools.biome
COMMAND ${CMAKE_Go_COMPILER} fmt ./...
COMMAND ${BIOME_EXECUTABLE} check --write --max-diagnostics=1000
)
add_custom_target(interface.typecheck
COMMENT "Type checking monetr's frontend code..."
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS tools.tsc
COMMAND ${TSC_EXECUTABLE} --noEmit --pretty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/interface
)
add_custom_target(emails.typecheck
COMMENT "Type checking monetr's email templates..."
DEPENDS tools.tsc
COMMAND ${TSC_EXECUTABLE} --noEmit --pretty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/emails
)
add_custom_target(docs.typecheck
COMMENT "Type checking monetr's documentation..."
DEPENDS tools.tsc
COMMAND ${TSC_EXECUTABLE} --noEmit --pretty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs
)
################################################################################
# TESTING #
################################################################################
enable_testing()
option(BUILD_TESTING "Build the testing tree." OFF)
include(GolangTestUtils)
if(BUILD_TESTING)
if(CMAKE_Go_COMPILER)
execute_process(
COMMAND ${CMAKE_Go_COMPILER} run ${CMAKE_SOURCE_DIR}/cmake/find_tests.go ${CMAKE_SOURCE_DIR}/server
OUTPUT_VARIABLE GOLANG_TEST_LIST
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
set(GOLANG_TEST_LIST "${GOLANG_TEST_LIST}" CACHE STRING "All Golang unit tests in json format." FORCE)
add_test(
NAME migrate.db
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} -t development.migrate
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# Migrations have to compile the server, which needs the CLDR dataset. This
# also keeps both of these from downloading it at the same time
set_tests_properties(migrate.db PROPERTIES FIXTURES_SETUP DB FIXTURES_REQUIRED cldr)
set_property(
TEST migrate.db
PROPERTY LABELS "bootstrap"
)
# The currency package embeds the CLDR dataset, so basically nothing in Go
# compiles until it's been downloaded
add_test(
NAME download.cldr-json
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} -t download.cldr-json
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
set_tests_properties(download.cldr-json PROPERTIES FIXTURES_SETUP cldr)
set_property(
TEST download.cldr-json
PROPERTY LABELS "bootstrap"
)
# If this test fails that means you need to run `go mod tidy`.
add_test(
NAME go.mod.tidy
COMMAND ${CMAKE_Go_COMPILER} mod tidy --diff
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
set_property(
TEST go.mod.tidy
PROPERTY LABELS "bootstrap"
)
else()
message(STATUS "Go tests will not be run since Go installation could not be found.")
endif()
add_test(
NAME ui.dependencies
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} -t dependencies.node_modules
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
set_tests_properties(ui.dependencies PROPERTIES FIXTURES_SETUP node_modules DEPENDS ${PNPM_EXECUTABLE})
set_property(
TEST ui.dependencies
PROPERTY LABELS "bootstrap"
)
set(INTERFACE_TEST_DIRECTORY ${CMAKE_BINARY_DIR}/tests/interface)
set(INTERFACE_COVERAGE_DIRECTORY ${INTERFACE_TEST_DIRECTORY}/coverage)
file(MAKE_DIRECTORY ${INTERFACE_TEST_DIRECTORY})
file(MAKE_DIRECTORY ${INTERFACE_COVERAGE_DIRECTORY})
set(INTERFACE_TEST_ARGS "run" "--config=${CMAKE_SOURCE_DIR}/interface/rstest.config.ts")
if(TEST_COVERAGE)
list(APPEND INTERFACE_TEST_ARGS "--coverage.enabled")
endif()
add_test(
NAME interface
COMMAND ${RSTEST_EXECUTABLE} ${INTERFACE_TEST_ARGS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/interface
)
set_tests_properties(interface PROPERTIES
FIXTURES_REQUIRED node_modules
TIMEOUT 120
LABELS "interface"
PROCESSORS 4
)
if(TEST_COVERAGE)
set_property(
TEST interface
PROPERTY ENVIRONMENT "RSTEST_COVERAGE_DIR=${INTERFACE_COVERAGE_DIRECTORY}"
)
endif()
add_test(
NAME interface.typecheck
COMMAND ${TSC_EXECUTABLE} --noEmit --pretty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/interface
)
set_tests_properties(interface.typecheck PROPERTIES
FIXTURES_REQUIRED node_modules
TIMEOUT 120
LABELS "interface"
PROCESSORS 2
)
add_test(
NAME emails.typecheck
COMMAND ${TSC_EXECUTABLE} --noEmit --pretty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/emails
)
set_tests_properties(emails.typecheck PROPERTIES
FIXTURES_REQUIRED node_modules
TIMEOUT 120
LABELS "emails"
PROCESSORS 2
)
add_test(
NAME docs.typecheck
COMMAND ${TSC_EXECUTABLE} --noEmit --pretty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs
)
set_tests_properties(docs.typecheck PROPERTIES
FIXTURES_REQUIRED node_modules
TIMEOUT 120
LABELS "docs"
PROCESSORS 2
)
# add_test(
# NAME renovate.validate
# COMMAND ${RENOVATE_CONFIG_VALIDATOR_EXECUTABLE} --strict
# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
# )
# set_tests_properties(renovate.validate PROPERTIES
# FIXTURES_REQUIRED node_modules
# FIXTURES_SETUP ui.dependencies
# TIMEOUT 60
# )
# set_property(
# TEST renovate.validate
# PROPERTY LABELS "renovate"
# )
endif()
file(GLOB_RECURSE SUB_PACKAGES RELATIVE ${CMAKE_SOURCE_DIR} "${CMAKE_SOURCE_DIR}/server/*CMakeLists.txt")
# # Loop through the files and get their directories
foreach(SUB_PACKAGE IN LISTS SUB_PACKAGES)
get_filename_component(DIR ${SUB_PACKAGE} DIRECTORY)
add_subdirectory(${DIR})
endforeach()
# In order for documentation tests to work this has to be after the tests are setup.
add_subdirectory("${CMAKE_SOURCE_DIR}/docs")
# Prevent caching of this value
unset(BUILD_TESTING)