mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
6fb4bb543a
Migrate package management from npm + Corepack to pnpm across the root,
web, and website workspaces:
- Swap npm/Corepack tooling for pnpm: drop package-lock.json files and the
bespoke Corepack bootstrap scripts (setup-corepack.mjs, utils/corepack.mjs,
lint-lockfile.mjs); add pnpm-lock.yaml + pnpm-workspace.yaml per workspace.
- CI uses the official pnpm/action-setup + actions/setup-node; pin the pnpm
store dir via PNPM_HOME so setup-node's `cache: pnpm` post-step succeeds.
- Docker sources pnpm from the official ghcr.io/pnpm/pnpm image via a
${BUILDPLATFORM}-pinned stage; the website docs build does a hoisted root
install so @goauthentik/docusaurus-config resolves its own deps.
- Gate the web install on the `node` dep so runtime-only jobs don't invoke
pnpm; scope the from-stable env setup so the new tooling doesn't run against
the stable checkout's npm packageManager field.
- Resolve @goauthentik/api (client-ts) from its TypeScript source instead of a
tsc-built dist, so it no longer depends on an install-time prepare having run
(the storybook build's environment never built it); sfe's rollup gains .ts
resolution to match.
- Netlify builds with pnpm; encode pnpm's supply-chain controls
(onlyBuiltDependencies/allowBuilds, minimumReleaseAge) in the workspace.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
368 lines
13 KiB
Makefile
368 lines
13 KiB
Makefile
.PHONY: gen dev-reset all clean test web docs
|
|
|
|
SHELL := /usr/bin/env bash
|
|
.SHELLFLAGS += ${SHELLFLAGS} -e -o pipefail
|
|
PWD = $(shell pwd)
|
|
UID = $(shell id -u)
|
|
GID = $(shell id -g)
|
|
PY_SOURCES = authentik packages tests scripts lifecycle .github
|
|
DOCKER_IMAGE ?= "authentik:test"
|
|
|
|
UNAME_S := $(shell uname -s)
|
|
ifeq ($(UNAME_S),Darwin)
|
|
SED_INPLACE = sed -i ''
|
|
else
|
|
SED_INPLACE = sed -i
|
|
endif
|
|
|
|
BREW_LDFLAGS :=
|
|
BREW_CPPFLAGS :=
|
|
BREW_PKG_CONFIG_PATH :=
|
|
|
|
CARGO := cargo
|
|
UV := uv
|
|
|
|
# For macOS users, add the libxml2 installed from brew libxmlsec1 to the build path
|
|
# to prevent SAML-related tests from failing and ensure correct pip dependency compilation
|
|
ifeq ($(UNAME_S),Darwin)
|
|
# Only add for brew users who installed libxmlsec1
|
|
BREW_EXISTS := $(shell command -v brew 2> /dev/null)
|
|
ifdef BREW_EXISTS
|
|
LIBXML2_EXISTS := $(shell brew list libxml2 2> /dev/null)
|
|
ifdef LIBXML2_EXISTS
|
|
_xml_pref := $(shell brew --prefix libxml2)
|
|
BREW_LDFLAGS += -L${_xml_pref}/lib
|
|
BREW_CPPFLAGS += -I${_xml_pref}/include
|
|
BREW_PKG_CONFIG_PATH = ${_xml_pref}/lib/pkgconfig:$(PKG_CONFIG_PATH)
|
|
endif
|
|
KRB5_EXISTS := $(shell brew list krb5 2> /dev/null)
|
|
ifdef KRB5_EXISTS
|
|
_krb5_pref := $(shell brew --prefix krb5)
|
|
BREW_LDFLAGS += -L${_krb5_pref}/lib
|
|
BREW_CPPFLAGS += -I${_krb5_pref}/include
|
|
BREW_PKG_CONFIG_PATH = ${_krb5_pref}/lib/pkgconfig:$(PKG_CONFIG_PATH)
|
|
endif
|
|
UV := LDFLAGS="$(BREW_LDFLAGS)" CPPFLAGS="$(BREW_CPPFLAGS)" PKG_CONFIG_PATH="$(BREW_PKG_CONFIG_PATH)" uv
|
|
endif
|
|
endif
|
|
|
|
NPM_VERSION :=
|
|
UV_EXISTS := $(shell command -v uv 2> /dev/null)
|
|
ifdef UV_EXISTS
|
|
NPM_VERSION := $(shell $(UV) run python -m scripts.generate_semver)
|
|
else
|
|
NPM_VERSION = $(shell python -m scripts.generate_semver)
|
|
endif
|
|
|
|
all: lint-fix lint gen web test ## Lint, build, and test everything
|
|
|
|
HELP_WIDTH := $(shell grep -h '^[a-z][^ ]*:.*\#\#' $(MAKEFILE_LIST) 2>/dev/null | \
|
|
cut -d':' -f1 | awk '{printf "%d\n", length}' | sort -rn | head -1)
|
|
|
|
help: ## Show this help
|
|
@echo "\nSpecify a command. The choices are:\n"
|
|
@grep -Eh '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
|
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[0;36m%-$(HELP_WIDTH)s \033[m %s\n", $$1, $$2}' | \
|
|
sort
|
|
@echo ""
|
|
|
|
go-test: ## Run the golang tests
|
|
go test -timeout 0 -v -race -cover ./...
|
|
|
|
rust-test: ## Run the Rust tests
|
|
$(CARGO) nextest run --workspace
|
|
|
|
test: ## Run the server tests and produce a coverage report (locally)
|
|
$(UV) run coverage run manage.py test --keepdb $(or $(filter-out $@ all,$(MAKECMDGOALS)),authentik)
|
|
$(UV) run coverage combine
|
|
$(UV) run coverage html
|
|
$(UV) run coverage report
|
|
|
|
lint-fix-rust:
|
|
$(CARGO) +nightly fmt --all -- --config-path "${PWD}/.cargo/rustfmt.toml"
|
|
|
|
lint-fix: lint-fix-rust ## Lint and automatically fix errors in the python source code. Reports spelling errors.
|
|
$(UV) run black $(PY_SOURCES)
|
|
$(UV) run ruff check --fix $(PY_SOURCES)
|
|
|
|
lint-spellcheck: ## Reports spelling errors.
|
|
npm run lint:spellcheck
|
|
|
|
lint: ci-lint-bandit ci-lint-mypy ci-lint-cargo-deny ci-lint-cargo-machete ## Lint the python and golang sources
|
|
golangci-lint run -v
|
|
|
|
core-install:
|
|
ifdef ($(BREW_EXISTS))
|
|
# Clear cache to ensure fresh compilation
|
|
$(UV) cache clean
|
|
# Force compilation from source for lxml and xmlsec with correct environment
|
|
$(UV) sync --frozen --reinstall-package lxml --reinstall-package xmlsec --no-binary-package lxml --no-binary-package xmlsec
|
|
else
|
|
$(UV) sync --frozen
|
|
endif
|
|
|
|
migrate: ## Run the Authentik Django server's migrations
|
|
$(UV) run python -m lifecycle.migrate
|
|
|
|
i18n-extract: core-i18n-extract web-i18n-extract ## Extract strings that require translation into files to send to a translation service
|
|
|
|
aws-cfn: node-install
|
|
pnpm --dir lifecycle/aws install
|
|
$(UV) run pnpm --dir lifecycle/aws run aws-cfn
|
|
|
|
run: ## Run the main authentik server and worker processes
|
|
$(UV) run ak allinone
|
|
|
|
run-watch: ## Run the authentik server and worker, with auto reloading
|
|
watchexec --on-busy-update=restart --stop-signal=SIGINT --exts py,rs,go --no-meta --notify -- $(UV) run ak allinone
|
|
|
|
core-i18n-extract:
|
|
$(UV) run ak makemessages \
|
|
--add-location file \
|
|
--no-obsolete \
|
|
--ignore web \
|
|
--ignore internal \
|
|
--ignore packages/client-ts \
|
|
--ignore website \
|
|
-l en
|
|
|
|
install: node-install web-install core-install ## Install all requires dependencies for `node`, `web` and `core`
|
|
|
|
dev-drop-db:
|
|
$(eval pg_user := $(shell $(UV) run python -m authentik.lib.config postgresql.user 2>/dev/null))
|
|
$(eval pg_host := $(shell $(UV) run python -m authentik.lib.config postgresql.host 2>/dev/null))
|
|
$(eval pg_name := $(shell $(UV) run python -m authentik.lib.config postgresql.name 2>/dev/null))
|
|
dropdb -U ${pg_user} -h ${pg_host} ${pg_name} || true
|
|
# Also remove the test-db if it exists
|
|
dropdb -U ${pg_user} -h ${pg_host} test_${pg_name} || true
|
|
|
|
dev-create-db:
|
|
$(eval pg_user := $(shell $(UV) run python -m authentik.lib.config postgresql.user 2>/dev/null))
|
|
$(eval pg_host := $(shell $(UV) run python -m authentik.lib.config postgresql.host 2>/dev/null))
|
|
$(eval pg_name := $(shell $(UV) run python -m authentik.lib.config postgresql.name 2>/dev/null))
|
|
createdb -U ${pg_user} -h ${pg_host} ${pg_name}
|
|
|
|
dev-reset: dev-drop-db dev-create-db migrate ## Drop and restore the Authentik PostgreSQL instance to a "fresh install" state.
|
|
|
|
update-test-mmdb: ## Update test GeoIP and ASN Databases
|
|
curl \
|
|
-L \
|
|
-o ${PWD}/tests/geoip/GeoLite2-ASN-Test.mmdb \
|
|
https://raw.githubusercontent.com/maxmind/MaxMind-DB/refs/heads/main/test-data/GeoLite2-ASN-Test.mmdb
|
|
curl \
|
|
-L \
|
|
-o ${PWD}/tests/geoip/GeoLite2-City-Test.mmdb \
|
|
https://raw.githubusercontent.com/maxmind/MaxMind-DB/refs/heads/main/test-data/GeoLite2-City-Test.mmdb
|
|
|
|
bump: ## Bump authentik version. Usage: make bump version=20xx.xx.xx
|
|
ifndef version
|
|
$(error Usage: make bump version=20xx.xx.xx )
|
|
endif
|
|
$(eval current_version := $(shell cat ${PWD}/internal/constants/VERSION))
|
|
$(SED_INPLACE) 's/^version = ".*"/version = "$(version)"/' ${PWD}/pyproject.toml
|
|
$(SED_INPLACE) 's/^VERSION = ".*"/VERSION = "$(version)"/' ${PWD}/authentik/__init__.py
|
|
$(SED_INPLACE) "s/version = \"${current_version}\"/version = \"$(version)\"/" ${PWD}/Cargo.toml ${PWD}/Cargo.lock
|
|
$(MAKE) gen-build gen-compose aws-cfn
|
|
$(SED_INPLACE) "s/\"${current_version}\"/\"$(version)\"/" ${PWD}/package.json ${PWD}/web/package.json
|
|
echo -n $(version) > ${PWD}/internal/constants/VERSION
|
|
|
|
#########################
|
|
## API Schema
|
|
#########################
|
|
|
|
gen-build: ## Extract the schema from the database
|
|
AUTHENTIK_DEBUG=true \
|
|
AUTHENTIK_TENANTS__ENABLED=true \
|
|
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
|
|
$(UV) run ak build_schema
|
|
|
|
gen-compose:
|
|
$(UV) run scripts/generate_compose.py
|
|
|
|
gen-changelog: ## (Release) generate the changelog based from the commits since the last version
|
|
# These are best-effort guesses based on commit messages
|
|
$(eval last_version := $(shell git tag --list 'version/*' --sort 'version:refname' | grep -vE 'rc\d+$$' | tail -1))
|
|
$(eval current_commit := $(shell git rev-parse HEAD))
|
|
git log --pretty=format:"- %s" $(shell git merge-base ${last_version} ${current_commit})...${current_commit} > merged_to_current
|
|
git log --pretty=format:"- %s" $(shell git merge-base ${last_version} ${current_commit})...${last_version} > merged_to_last
|
|
grep -Eo 'cherry-pick (#\d+)' merged_to_last | cut -d ' ' -f 2 | sed 's/.*/(&)$$/' > cherry_picked_to_last
|
|
grep -vf cherry_picked_to_last merged_to_current | grep -vE '^- (ci:|website)' | sort > changelog.md
|
|
rm merged_to_current
|
|
rm merged_to_last
|
|
rm cherry_picked_to_last
|
|
npx prettier --write changelog.md
|
|
|
|
gen-diff: ## (Release) generate the changelog diff between the current schema and the last version
|
|
$(eval last_version := $(shell git tag --list 'version/*' --sort 'version:refname' | grep -vE 'rc\d+$$' | tail -1))
|
|
git show ${last_version}:schema.yml > schema-old.yml
|
|
docker compose -f scripts/compose.yml run --rm --user "${UID}:${GID}" diff \
|
|
--markdown \
|
|
/local/diff.md \
|
|
/local/schema-old.yml \
|
|
/local/schema.yml
|
|
rm schema-old.yml
|
|
$(SED_INPLACE) 's/{/\{/g' diff.md
|
|
$(SED_INPLACE) 's/}/\}/g' diff.md
|
|
npx prettier --write diff.md
|
|
|
|
gen-client-go: ## Build and install the authentik API for Golang
|
|
$(UV) run make -C "${PWD}/packages/client-go" build
|
|
|
|
gen-client-rust: ## Build and install the authentik API for Rust
|
|
$(UV) run make -C "${PWD}/packages/client-rust" build version=${NPM_VERSION}
|
|
make lint-fix-rust
|
|
|
|
gen-client-ts: ## Build and install the authentik API for Typescript into the authentik UI Application
|
|
make -C "${PWD}/packages/client-ts" build
|
|
pnpm --dir web install
|
|
|
|
_gen-clients: gen-client-go gen-client-rust gen-client-ts
|
|
gen-clients: ## Build and install API clients used by authentik
|
|
$(MAKE) _gen-clients -j
|
|
|
|
gen: gen-build gen-clients ## Build and install API schema and clients used by authentik
|
|
|
|
gen-dev-config: ## Generate a local development config file
|
|
$(UV) run scripts/generate_config.py
|
|
|
|
#########################
|
|
## Node.js
|
|
#########################
|
|
|
|
# Lifecycle scripts are blocked by default in pnpm 10+ via
|
|
# `pnpm-workspace.yaml#onlyBuiltDependencies`. Adding a package to that list
|
|
# grants it arbitrary code execution at install — audit at review time.
|
|
|
|
node-preinstall: ## Verify the active Node.js and pnpm versions match what's in package.json.
|
|
node ./scripts/node/lint-runtime.mjs
|
|
|
|
node-install: node-preinstall ## Install the necessary libraries to build Node.js packages
|
|
pnpm install --frozen-lockfile
|
|
|
|
#########################
|
|
## Web
|
|
#########################
|
|
|
|
web-install: ## Install the necessary libraries to build the Authentik UI
|
|
pnpm --dir web install --frozen-lockfile
|
|
|
|
web-build: node-install ## Build the Authentik UI
|
|
pnpm --dir web run build
|
|
|
|
web: web-lint-fix web-lint web-check-compile ## Automatically fix formatting issues in the Authentik UI source code, lint the code, and compile it
|
|
|
|
web-test: ## Run tests for the Authentik UI
|
|
pnpm --dir web run test
|
|
|
|
web-watch: ## Build and watch the Authentik UI for changes, updating automatically
|
|
pnpm --dir web run watch
|
|
web-storybook-watch: ## Build and run the storybook documentation server
|
|
pnpm --dir web run storybook
|
|
|
|
web-lint-fix:
|
|
pnpm --dir web run prettier
|
|
|
|
web-lint:
|
|
pnpm --dir web run lint
|
|
pnpm --dir web run lit-analyse
|
|
|
|
web-check-compile:
|
|
pnpm --dir web run tsc
|
|
|
|
web-i18n-extract:
|
|
pnpm --dir web run extract-locales
|
|
|
|
#########################
|
|
## Docs
|
|
#########################
|
|
|
|
docs: docs-lint-fix docs-build ## Automatically fix formatting issues in the Authentik docs source code, lint the code, and compile it
|
|
|
|
docs-install: node-install ## Install the necessary libraries to build the Authentik documentation
|
|
pnpm --dir website install --frozen-lockfile
|
|
|
|
docs-lint-fix: lint-spellcheck
|
|
pnpm --dir website run prettier
|
|
|
|
docs-build:
|
|
node ./scripts/node/lint-runtime.mjs website
|
|
pnpm --dir website run build
|
|
|
|
docs-watch: ## Build and watch the topics documentation
|
|
pnpm --dir website run start
|
|
|
|
integrations: docs-lint-fix integrations-build ## Fix formatting issues in the integrations source code, lint the code, and compile it
|
|
|
|
integrations-build:
|
|
pnpm --dir website run build:integrations
|
|
|
|
integrations-watch: ## Build and watch the Integrations documentation
|
|
pnpm --filter "./website/integrations" run start
|
|
|
|
docs-api-build:
|
|
pnpm --dir website run build:api
|
|
|
|
docs-api-watch: ## Build and watch the API documentation
|
|
pnpm --filter "./website/api" run generate
|
|
pnpm --filter "./website/api" run start
|
|
|
|
docs-api-clean: ## Clean generated API documentation
|
|
pnpm --filter "./website/api" run clean
|
|
|
|
#########################
|
|
## Docker
|
|
#########################
|
|
|
|
docker: ## Build a docker image of the current source tree
|
|
DOCKER_BUILDKIT=1 docker build . -f lifecycle/container/Dockerfile --progress plain --tag ${DOCKER_IMAGE}
|
|
|
|
test-docker:
|
|
BUILD=true ${PWD}/scripts/test_docker.sh
|
|
|
|
#########################
|
|
## CI
|
|
#########################
|
|
# These targets are use by GitHub actions to allow usage of matrix
|
|
# which makes the YAML File a lot smaller
|
|
|
|
ci--meta-debug:
|
|
$(UV) run python -V || echo "No python installed"
|
|
$(CARGO) --version || echo "No rust installed"
|
|
node --version || echo "No node installed"
|
|
|
|
ci-lint-mypy: ci--meta-debug
|
|
$(UV) run mypy --strict $(PY_SOURCES)
|
|
|
|
ci-lint-black: ci--meta-debug
|
|
$(UV) run black --check $(PY_SOURCES)
|
|
|
|
ci-lint-ruff: ci--meta-debug
|
|
$(UV) run ruff check $(PY_SOURCES)
|
|
|
|
ci-lint-spellcheck: ci--meta-debug
|
|
npm run lint:spellcheck
|
|
|
|
ci-lint-bandit: ci--meta-debug
|
|
$(UV) run bandit -c pyproject.toml -r $(PY_SOURCES) -iii
|
|
|
|
ci-lint-pending-migrations: ci--meta-debug
|
|
$(UV) run ak makemigrations --check
|
|
|
|
ci-lint-cargo-deny: ci--meta-debug
|
|
$(CARGO) deny --locked --workspace check --config "${PWD}/.cargo/deny.toml"
|
|
|
|
ci-lint-cargo-machete: ci--meta-debug
|
|
$(CARGO) machete
|
|
|
|
ci-lint-rustfmt: ci--meta-debug
|
|
$(CARGO) +nightly fmt --all --check -- --config-path "${PWD}/.cargo/rustfmt.toml"
|
|
|
|
ci-lint-clippy: ci--meta-debug
|
|
$(CARGO) clippy --workspace -- -D warnings
|
|
|
|
ci-test: ci--meta-debug
|
|
$(UV) run coverage run manage.py test --keepdb --parallel auto authentik
|
|
$(UV) run coverage combine
|
|
$(UV) run coverage report
|
|
$(UV) run coverage xml
|