Compare commits
	
		
			2 Commits
		
	
	
		
			npm-worksp
			...
			openapi-ge
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b8c96c88f5 | |||
| 16019b8585 | 
							
								
								
									
										94
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,6 +1,7 @@ | ||||
| .PHONY: gen dev-reset all clean test web website | ||||
|  | ||||
| .SHELLFLAGS += ${SHELLFLAGS} -e | ||||
| SHELL := /usr/bin/env bash | ||||
| .SHELLFLAGS += ${SHELLFLAGS} -e -o pipefail | ||||
| PWD = $(shell pwd) | ||||
| UID = $(shell id -u) | ||||
| GID = $(shell id -g) | ||||
| @ -8,9 +9,9 @@ NPM_VERSION = $(shell python -m scripts.generate_semver) | ||||
| PY_SOURCES = authentik tests scripts lifecycle .github | ||||
| DOCKER_IMAGE ?= "authentik:test" | ||||
|  | ||||
| GEN_API_TS = "gen-ts-api" | ||||
| GEN_API_PY = "gen-py-api" | ||||
| GEN_API_GO = "gen-go-api" | ||||
| GEN_API_TS = gen-ts-api | ||||
| GEN_API_PY = gen-py-api | ||||
| GEN_API_GO = gen-go-api | ||||
|  | ||||
| pg_user := $(shell uv run python -m authentik.lib.config postgresql.user 2>/dev/null) | ||||
| pg_host := $(shell uv run python -m authentik.lib.config postgresql.host 2>/dev/null) | ||||
| @ -117,63 +118,45 @@ gen-diff:  ## (Release) generate the changelog diff between the current schema a | ||||
| 	npx prettier --write diff.md | ||||
|  | ||||
| gen-clean-ts:  ## Remove generated API client for Typescript | ||||
| 	rm -rf ./${GEN_API_TS}/ | ||||
| 	rm -rf ./web/node_modules/@goauthentik/api/ | ||||
| 	rm -rf ${PWD}/${GEN_API_TS}/ | ||||
| 	rm -rf ${PWD}/web/node_modules/@goauthentik/api/ | ||||
|  | ||||
| gen-clean-go:  ## Remove generated API client for Go | ||||
| 	rm -rf ./${GEN_API_GO}/ | ||||
| gen-clean-go:  ## Remove generated API client for Go | ||||
| 	mkdir -p ${PWD}/${GEN_API_GO} | ||||
| ifneq ($(wildcard ${PWD}/${GEN_API_GO}/.*),) | ||||
| 	make -C ${PWD}/${GEN_API_GO} clean | ||||
| else | ||||
| 	rm -rf ${PWD}/${GEN_API_GO} | ||||
| endif | ||||
|  | ||||
| gen-clean-py:  ## Remove generated API client for Python | ||||
| 	rm -rf ./${GEN_API_PY}/ | ||||
| gen-clean-py:  ## Remove generated API client for Python | ||||
| 	rm -rf ${PWD}/${GEN_API_PY}/ | ||||
|  | ||||
| gen-clean: gen-clean-ts gen-clean-go gen-clean-py  ## Remove generated API clients | ||||
|  | ||||
| gen-client-ts: gen-clean-ts  ## Build and install the authentik API for Typescript into the authentik UI Application | ||||
| 	docker run \ | ||||
| 		--rm -v ${PWD}:/local \ | ||||
| 		--user ${UID}:${GID} \ | ||||
| 		docker.io/openapitools/openapi-generator-cli:v7.11.0 generate \ | ||||
| 		-i /local/schema.yml \ | ||||
| 		-g typescript-fetch \ | ||||
| 		-o /local/${GEN_API_TS} \ | ||||
| 		-c /local/scripts/api-ts-config.yaml \ | ||||
| 		--additional-properties=npmVersion=${NPM_VERSION} \ | ||||
| 		--git-repo-id authentik \ | ||||
| 		--git-user-id goauthentik | ||||
| 	mkdir -p web/node_modules/@goauthentik/api | ||||
| 	cd ./${GEN_API_TS} && npm i | ||||
| 	\cp -rf ./${GEN_API_TS}/* web/node_modules/@goauthentik/api | ||||
|     ./scripts/gen-client-ts.mjs | ||||
|  | ||||
|     npm i --prefix ${GEN_API_TS} | ||||
|  | ||||
|     cd ./${GEN_API_TS} && npm link | ||||
|     cd ./web && npm link @goauthentik/api | ||||
|  | ||||
| gen-client-py: gen-clean-py ## Build and install the authentik API for Python | ||||
| 	docker run \ | ||||
| 		--rm -v ${PWD}:/local \ | ||||
| 		--user ${UID}:${GID} \ | ||||
| 		docker.io/openapitools/openapi-generator-cli:v7.11.0 generate \ | ||||
| 		-i /local/schema.yml \ | ||||
| 		-g python \ | ||||
| 		-o /local/${GEN_API_PY} \ | ||||
| 		-c /local/scripts/api-py-config.yaml \ | ||||
| 		--additional-properties=packageVersion=${NPM_VERSION} \ | ||||
| 		--git-repo-id authentik \ | ||||
| 		--git-user-id goauthentik | ||||
|     ./scripts/gen-client-py.mjs | ||||
|  | ||||
| 	pip install ./${GEN_API_PY} | ||||
|  | ||||
| gen-client-go: gen-clean-go  ## Build and install the authentik API for Golang | ||||
| 	mkdir -p ./${GEN_API_GO} ./${GEN_API_GO}/templates | ||||
| 	wget https://raw.githubusercontent.com/goauthentik/client-go/main/config.yaml -O ./${GEN_API_GO}/config.yaml | ||||
| 	wget https://raw.githubusercontent.com/goauthentik/client-go/main/templates/README.mustache -O ./${GEN_API_GO}/templates/README.mustache | ||||
| 	wget https://raw.githubusercontent.com/goauthentik/client-go/main/templates/go.mod.mustache -O ./${GEN_API_GO}/templates/go.mod.mustache | ||||
| 	cp schema.yml ./${GEN_API_GO}/ | ||||
| 	docker run \ | ||||
| 		--rm -v ${PWD}/${GEN_API_GO}:/local \ | ||||
| 		--user ${UID}:${GID} \ | ||||
| 		docker.io/openapitools/openapi-generator-cli:v6.5.0 generate \ | ||||
| 		-i /local/schema.yml \ | ||||
| 		-g go \ | ||||
| 		-o /local/ \ | ||||
| 		-c /local/config.yaml | ||||
| 	mkdir -p ${PWD}/${GEN_API_GO} | ||||
| ifeq ($(wildcard ${PWD}/${GEN_API_GO}/.*),) | ||||
| 	git clone --depth 1 https://github.com/goauthentik/client-go.git ${PWD}/${GEN_API_GO} | ||||
| else | ||||
| 	cd ${PWD}/${GEN_API_GO} && git pull | ||||
| endif | ||||
| 	cp ${PWD}/schema.yml ${PWD}/${GEN_API_GO} | ||||
| 	make -C ${PWD}/${GEN_API_GO} build | ||||
| 	go mod edit -replace goauthentik.io/api/v3=./${GEN_API_GO} | ||||
| 	rm -rf ./${GEN_API_GO}/config.yaml ./${GEN_API_GO}/templates/ | ||||
|  | ||||
| gen-dev-config:  ## Generate a local development config file | ||||
| 	uv run scripts/generate_config.py | ||||
| @ -244,7 +227,7 @@ docker:  ## Build a docker image of the current source tree | ||||
| 	DOCKER_BUILDKIT=1 docker build . --progress plain --tag ${DOCKER_IMAGE} | ||||
|  | ||||
| test-docker: | ||||
| 	BUILD=true ./scripts/test_docker.sh | ||||
| 	BUILD=true ${PWD}/scripts/test_docker.sh | ||||
|  | ||||
| ######################### | ||||
| ## CI | ||||
| @ -264,14 +247,3 @@ ci-ruff: ci--meta-debug | ||||
|  | ||||
| ci-codespell: ci--meta-debug | ||||
| 	uv run codespell -s | ||||
|  | ||||
| ci-bandit: ci--meta-debug | ||||
| 	uv run bandit -r $(PY_SOURCES) | ||||
|  | ||||
| ci-pending-migrations: ci--meta-debug | ||||
| 	uv run ak makemigrations --check | ||||
|  | ||||
| ci-test: ci--meta-debug | ||||
| 	uv run coverage run manage.py test --keepdb --randomly-seed ${CI_TEST_SEED} authentik | ||||
| 	uv run coverage report | ||||
| 	uv run coverage xml | ||||
|  | ||||
							
								
								
									
										19
									
								
								scripts/gen-client-py.mjs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								scripts/gen-client-py.mjs
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,19 @@ | ||||
| #!/usr/bin/env node | ||||
| /** | ||||
|  * @file Generates the authentik API client for Python. | ||||
|  */ | ||||
| import { dirname, resolve } from "node:path"; | ||||
| import { fileURLToPath } from "node:url"; | ||||
|  | ||||
| import { generateOpenAPIClient } from "./openapi-generator.mjs"; | ||||
|  | ||||
| const scriptDirectory = dirname(fileURLToPath(import.meta.url)); | ||||
|  | ||||
| const repoRoot = resolve(scriptDirectory, ".."); | ||||
|  | ||||
| generateOpenAPIClient({ | ||||
|     cwd: repoRoot, | ||||
|     outputDirectory: resolve(repoRoot, "gen-py-api"), | ||||
|     generatorName: "python", | ||||
|     config: resolve(scriptDirectory, "api-py-config.yaml"), | ||||
| }); | ||||
							
								
								
									
										22
									
								
								scripts/gen-client-ts.mjs
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								scripts/gen-client-ts.mjs
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,22 @@ | ||||
| #!/usr/bin/env node | ||||
| /** | ||||
|  * @file Generates the authentik API client for TypeScript. | ||||
|  */ | ||||
| import { dirname, resolve } from "node:path"; | ||||
| import { fileURLToPath } from "node:url"; | ||||
|  | ||||
| import PackageJSON from "../package.json" with { type: "json" }; | ||||
| import { generateOpenAPIClient } from "./openapi-generator.mjs"; | ||||
|  | ||||
| const scriptDirectory = dirname(fileURLToPath(import.meta.url)); | ||||
|  | ||||
| const repoRoot = resolve(scriptDirectory, ".."); | ||||
| const npmVersion = [PackageJSON.version, Date.now()].join("-"); | ||||
|  | ||||
| generateOpenAPIClient({ | ||||
|     cwd: repoRoot, | ||||
|     outputDirectory: resolve(repoRoot, "gen-ts-api"), | ||||
|     generatorName: "typescript-fetch", | ||||
|     config: resolve(scriptDirectory, "api-ts-config.yaml"), | ||||
|     commandArgs: [`--additional-properties=npmVersion=${npmVersion}`], | ||||
| }); | ||||
| @ -1,15 +0,0 @@ | ||||
| #!/usr/bin/env python3 | ||||
| """ | ||||
| Generates a Semantic Versioning identifier, suffixed with a timestamp. | ||||
| """ | ||||
|  | ||||
| from time import time | ||||
|  | ||||
| from authentik import __version__ as package_version | ||||
|  | ||||
| """ | ||||
| See: https://semver.org/#spec-item-9 (Pre-release spec) | ||||
| """ | ||||
| pre_release_timestamp = int(time()) | ||||
|  | ||||
| print(f"{package_version}-{pre_release_timestamp}") | ||||
							
								
								
									
										100
									
								
								scripts/openapi-generator.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								scripts/openapi-generator.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | ||||
| /** | ||||
|  * @file OpenAPI generator utilities. | ||||
|  */ | ||||
| import { execFileSync, execSync } from "node:child_process"; | ||||
| import { existsSync, rmSync } from "node:fs"; | ||||
| import { userInfo } from "node:os"; | ||||
| import { join, relative, resolve } from "node:path"; | ||||
|  | ||||
| const OPENAPI_CONTAINER_IMAGE = "docker.io/openapitools/openapi-generator-cli:v7.11.0"; | ||||
|  | ||||
| /** | ||||
|  * Checks if a command exists in the PATH. | ||||
|  * | ||||
|  * @template {string} T | ||||
|  * @param {T} command | ||||
|  * @returns {T | null} | ||||
|  */ | ||||
| function commandExists(command) { | ||||
|     if (execSync(`command -v ${command} || echo ''`).toString().trim()) { | ||||
|         return command; | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Given a path relative to the current working directory, | ||||
|  * resolves it to a path relative to the local volume. | ||||
|  * | ||||
|  * @param {string} cwd | ||||
|  * @param {...string} pathSegments | ||||
|  */ | ||||
| function resolveLocalPath(cwd, ...pathSegments) { | ||||
|     return resolve("/local", relative(cwd, join(...pathSegments))); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @typedef {object} GenerateOpenAPIClientOptions | ||||
|  * @property {string} cwd The working directory to run the generator in. | ||||
|  * @property {string} outputDirectory The path to the output directory. | ||||
|  * @property {string} generatorName The name of the generator. | ||||
|  * @property {string} config The path to the generator configuration. | ||||
|  * @property {string} [inputSpec] The path to the OpenAPI specification. | ||||
|  * @property {Array<string | string[]>} [commandArgs] Additional arguments to pass to the generator. | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * Generates an OpenAPI client using the `openapi-generator-cli` Docker image. | ||||
|  * | ||||
|  * @param {GenerateOpenAPIClientOptions} options | ||||
|  * @see {@link https://openapi-generator.tech/docs/usage} | ||||
|  */ | ||||
| export function generateOpenAPIClient({ | ||||
|     cwd, | ||||
|     outputDirectory, | ||||
|     generatorName, | ||||
|     config, | ||||
|     inputSpec = resolve(cwd, "schema.yml"), | ||||
|     commandArgs = [], | ||||
| }) { | ||||
|     if (existsSync(outputDirectory)) { | ||||
|         console.log(`Removing existing generated API client from ${outputDirectory}`); | ||||
|  | ||||
|         rmSync(outputDirectory, { recursive: true, force: true }); | ||||
|     } | ||||
|  | ||||
|     const containerEngine = commandExists("docker") || commandExists("podman"); | ||||
|  | ||||
|     if (!containerEngine) { | ||||
|         throw new Error("Container engine not found. Is Docker or Podman available in the PATH?"); | ||||
|     } | ||||
|  | ||||
|     const { gid, uid } = userInfo(); | ||||
|  | ||||
|     const args = [ | ||||
|         "run", | ||||
|         [`--user`, `${uid}:${gid}`], | ||||
|         `--rm`, | ||||
|         [`-v`, `${cwd}:/local`], | ||||
|         OPENAPI_CONTAINER_IMAGE, | ||||
|         "generate", | ||||
|         ["--input-spec", resolveLocalPath(cwd, inputSpec)], | ||||
|         [`--generator-name`, generatorName], | ||||
|         ["--config", resolveLocalPath(cwd, config)], | ||||
|         ["--git-repo-id", `authentik`], | ||||
|         ["--git-user-id", `goauthentik`], | ||||
|         ["--output", resolveLocalPath(cwd, outputDirectory)], | ||||
|  | ||||
|         ...commandArgs, | ||||
|     ]; | ||||
|  | ||||
|     console.debug(`Running command: ${containerEngine}`, args); | ||||
|  | ||||
|     execFileSync(containerEngine, args.flat(), { | ||||
|         cwd, | ||||
|         stdio: "inherit", | ||||
|     }); | ||||
|  | ||||
|     console.log(`Generated API client to ${outputDirectory}`); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	