Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/actions/install-uv/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Install uv
description: |
Install uv with the version pinned in api/pyproject.toml's
[tool.uv] required-version, with the uv cache enabled and
invalidated against api/uv.lock.

inputs:
python-version:
description: Python version to install
required: true

runs:
using: composite
steps:
- uses: astral-sh/setup-uv@v6
with:
version-file: api/pyproject.toml
python-version: ${{ inputs.python-version }}
enable-cache: true
cache-dependency-glob: api/uv.lock
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

version: 2
updates:
- package-ecosystem: "pip"
- package-ecosystem: "uv"
# we only want security updates from dependabot, so we set the limit to 0
# for regular updates. See documentation for further information here:
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#open-pull-requests-limit-
Expand Down
10 changes: 3 additions & 7 deletions .github/workflows/api-deploy-production-ecs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,16 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Install Poetry
run: make install-poetry

- name: Set up Python
uses: actions/setup-python@v5
- name: Install uv
uses: ./.github/actions/install-uv
with:
python-version: "3.12"
cache: poetry

- name: Install dependencies
run: |
echo "https://${{ secrets.GH_PRIVATE_ACCESS_TOKEN }}:@github.com" > ${HOME}/.git-credentials
git config --global credential.helper store
make install-packages opts="--with saml,auth-controller,workflows,release-pipelines"
make install-packages opts="--extra saml --extra auth-controller --extra workflows --extra release-pipelines"
make install-private-modules
rm -rf ${HOME}/.git-credentials

Expand Down
9 changes: 3 additions & 6 deletions .github/workflows/api-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,13 @@ jobs:
- name: Cloning repo
uses: actions/checkout@v5

- name: Install Poetry
run: make install-poetry

- uses: actions/setup-python@v5
- name: Install uv
uses: ./.github/actions/install-uv
with:
python-version: ${{ matrix.python-version }}
cache: poetry

- name: Install Dependencies
run: make install-packages
run: make install-packages opts='--extra dev'

- name: Check for missing migrations
env:
Expand Down
9 changes: 3 additions & 6 deletions .github/workflows/api-run-makefile-target.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,13 @@ jobs:
steps:
- uses: actions/checkout@v5

- name: Install Poetry
run: make install-poetry

- uses: actions/setup-python@v5
- name: Install uv
uses: ./.github/actions/install-uv
with:
python-version: 3.13
cache: poetry

- name: Install Dependencies
run: make install-packages
run: make install-packages opts='--extra dev'

- name: Run `make ${{ inputs.target }} opts=${{ inputs.opts }}`
env:
Expand Down
9 changes: 3 additions & 6 deletions .github/workflows/api-tests-with-private-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,10 @@ jobs:
- name: Cloning repo
uses: actions/checkout@v5

- name: Install Poetry
run: make install-poetry

- uses: actions/setup-python@v5
- name: Install uv
uses: ./.github/actions/install-uv
with:
python-version: ${{ matrix.python-version }}
cache: poetry

- name: Install SAML Dependencies
run: sudo apt-get install -y xmlsec1
Expand All @@ -56,7 +53,7 @@ jobs:
run: |
echo "https://${{ secrets.GH_PRIVATE_ACCESS_TOKEN }}:@github.com" > ${HOME}/.git-credentials
git config --global credential.helper store
make install-packages opts="--with saml,auth-controller,workflows"
make install-packages opts="--extra dev --extra saml --extra auth-controller --extra workflows"
make install-private-modules
make integrate-private-tests
rm -rf ${HOME}/.git-credentials
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/update-flagsmith-environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@ jobs:
steps:
- uses: actions/checkout@v5

- name: Set up Python 3.12
uses: actions/setup-python@v5
- name: Install uv
uses: ./.github/actions/install-uv
with:
python-version: 3.12
cache: pip

- name: Install Dependencies
run: make install
run: make install-packages

- name: Update defaults
run: poetry run python manage.py updateflagsmithenvironment
run: uv run python manage.py updateflagsmithenvironment

- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ repos:
- id: python-typecheck
name: python-typecheck
language: system
entry: poetry -C api run mypy .
entry: uv run --directory api mypy .
require_serial: true
pass_filenames: false
types: [python]
Expand All @@ -48,11 +48,11 @@ repos:
hooks:
- id: flagsmith-lint-tests

- repo: https://github.com/python-poetry/poetry
rev: 2.4.0
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.8.14
hooks:
- id: poetry-check
args: ["-C", "api"]
- id: uv-lock
args: ["--project", "api", "--check"]

default_install_hook_types: [pre-commit, pre-push]
default_stages: [pre-commit]
Expand Down
28 changes: 16 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,15 @@ RUN apk add build-base linux-headers curl git \
python-${PYTHON_VERSION}-dev \
py${PYTHON_VERSION}-pip

COPY api/pyproject.toml api/poetry.lock api/Makefile ./
ENV POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_VIRTUALENVS_OPTIONS_ALWAYS_COPY=true \
POETRY_VIRTUALENVS_OPTIONS_NO_PIP=true \
POETRY_VIRTUALENVS_OPTIONS_NO_SETUPTOOLS=true \
POETRY_HOME=/opt/poetry \
PATH="/opt/poetry/bin:$PATH"
RUN make install opts='--without dev'
COPY api/pyproject.toml api/uv.lock api/Makefile ./
ENV UV_PROJECT_ENVIRONMENT=/build/.venv \
UV_PYTHON_PREFERENCE=only-system \
UV_PYTHON=python${PYTHON_VERSION} \
UV_LINK_MODE=copy \
UV_NO_SYNC=1 \
UV_CACHE_DIR=/root/.cache/uv
RUN --mount=type=cache,target=/root/.cache/uv \
make install opts='--no-install-project'

# * build-python-private [build-python]
FROM build-python AS build-python-private
Expand All @@ -109,11 +110,12 @@ FROM build-python AS build-python-private
# and integrate private modules
ARG SAML_REVISION
ARG RBAC_REVISION
ARG WITH="saml,auth-controller,ldap,workflows,licensing,release-pipelines"
ARG EXTRAS="--extra saml --extra auth-controller --extra ldap --extra workflows --extra licensing --extra release-pipelines"
RUN --mount=type=secret,id=github_private_cloud_token \
--mount=type=cache,target=/root/.cache/uv \
echo "https://$(cat /run/secrets/github_private_cloud_token):@github.com" > ${HOME}/.git-credentials && \
git config --global credential.helper store && \
make install-packages opts='--without dev --with ${WITH}' && \
make install-packages opts="--no-install-project ${EXTRAS}" && \
make install-private-modules

# * api-runtime
Expand Down Expand Up @@ -161,7 +163,8 @@ FROM build-python AS api-test

COPY api /build/

RUN make install-packages opts='--with dev'
RUN --mount=type=cache,target=/root/.cache/uv \
make install-packages opts='--extra dev'

CMD ["make", "test"]

Expand All @@ -170,7 +173,8 @@ FROM build-python-private AS api-private-test

COPY api /build/

RUN make install-packages opts='--with dev' && \
RUN --mount=type=cache,target=/root/.cache/uv \
make install-packages opts='--extra dev --extra saml --extra auth-controller --extra ldap --extra workflows --extra licensing --extra release-pipelines' && \
make integrate-private-tests && \
git config --global --unset credential.helper && \
rm -f ${HOME}/.git-credentials
Expand Down
60 changes: 30 additions & 30 deletions api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ COMPOSE_PROJECT_NAME ?= flagsmith

DOTENV_OVERRIDE_FILE ?= .env

POETRY_VERSION ?= 2.2.1
UV_VERSION ?= $(shell python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["tool"]["uv"]["required-version"].lstrip("="))')

SAML_REVISION ?= v1.6.6
RBAC_REVISION ?= v0.13.0
Expand All @@ -21,32 +21,32 @@ OPENAPI_FORMAT_VERSION ?= 1.23.0
install-pip:
python -m pip -q install --upgrade pip

.PHONY: install-poetry
install-poetry:
python -m pip -q install poetry==${POETRY_VERSION}
.PHONY: install-uv
install-uv:
python -m pip -q install uv==${UV_VERSION}

.PHONY: install-packages
install-packages:
poetry install --no-root $(opts)
uv sync --frozen $(opts)

.PHONY: install-private-modules
install-private-modules:
$(eval SITE_PACKAGES_DIR := $(shell poetry run python -c 'import site; print(site.getsitepackages()[0])'))
$(eval SITE_PACKAGES_DIR := $(shell uv run python -c 'import site; print(site.getsitepackages()[0])'))
rm -rf $(SITE_PACKAGES_DIR)/saml $(SITE_PACKAGES_DIR)/rbac
git clone https://github.com/flagsmith/flagsmith-saml --depth 1 --branch ${SAML_REVISION} && mv ./flagsmith-saml/saml $(SITE_PACKAGES_DIR)
git clone https://github.com/flagsmith/flagsmith-rbac --depth 1 --branch ${RBAC_REVISION} && mv ./flagsmith-rbac/rbac $(SITE_PACKAGES_DIR)
rm -rf ./flagsmith-saml ./flagsmith-rbac

.PHONY: install
install: install-pip install-poetry install-packages
install: install-pip install-uv install-packages

.PHONY: lint
lint:
poetry run pre-commit run -a
uv run pre-commit run -a

.PHONY: typecheck
typecheck:
poetry run mypy .
uv run mypy .

.PHONY: docker-up
docker-up:
Expand All @@ -71,44 +71,44 @@ docker-build:

.PHONY: wait-for-db
wait-for-db:
poetry run python manage.py waitfordb
poetry run python manage.py waitfordb --database analytics
uv run python manage.py waitfordb
uv run python manage.py waitfordb --database analytics

.PHONY: test
test: docker-up wait-for-db
poetry run pytest $(opts)
uv run pytest $(opts)

.PHONY: django-make-migrations
django-make-migrations: docker-up wait-for-db
poetry run python manage.py waitfordb
poetry run python manage.py makemigrations $(opts)
uv run python manage.py waitfordb
uv run python manage.py makemigrations $(opts)

.PHONY: django-squash-migrations
django-squash-migrations: docker-up wait-for-db
poetry run python manage.py waitfordb
poetry run python manage.py squashmigrations $(opts)
uv run python manage.py waitfordb
uv run python manage.py squashmigrations $(opts)

.PHONY: django-migrate
django-migrate: docker-up wait-for-db
poetry run python manage.py waitfordb
poetry run python manage.py migrate
poetry run python manage.py createcachetable
uv run python manage.py waitfordb
uv run python manage.py migrate
uv run python manage.py createcachetable

.PHONY: django-shell
django-shell:
poetry run python manage.py shell_plus
uv run python manage.py shell_plus

.PHONY: django-collect-static
django-collect-static:
poetry run python manage.py collectstatic --noinput
uv run python manage.py collectstatic --noinput

.PHONY: serve
serve: docker-up wait-for-db
poetry run flagsmith start --reload api
uv run flagsmith start --reload api

.PHONY: run-task-processor
run-task-processor: docker-up wait-for-db
poetry run flagsmith start --reload --bind 0.0.0.0:8001 task-processor
uv run flagsmith start --reload --bind 0.0.0.0:8001 task-processor

.PHONY: serve-with-task-processor
serve-with-task-processor: TASK_RUN_METHOD=TASK_PROCESSOR
Expand All @@ -118,7 +118,7 @@ serve-with-task-processor:
.PHONY: generate-flagsmith-sdk-openapi
generate-flagsmith-sdk-openapi: OPENAPI_SERVERS=[{"url": "https://edge.api.flagsmith.com", "description": "Flagsmith Edge API"}]
generate-flagsmith-sdk-openapi:
poetry run python manage.py spectacular | \
uv run python manage.py spectacular | \
npx openapi-format@${OPENAPI_FORMAT_VERSION} /dev/fd/0 \
--filterFile openapi-filter-flagsmith-sdk.yml \
--output ../sdk/openapi.yaml
Expand Down Expand Up @@ -153,8 +153,8 @@ generate-grafana-client-types:

.PHONY: integrate-private-tests
integrate-private-tests:
$(eval WORKFLOW_REVISION := $(shell grep -A 1 "\[tool.poetry.group.workflows.dependencies\]" pyproject.toml | awk -F '"' '{printf $$4}'))
$(eval AUTH_CONTROLLER_REVISION := $(shell grep -A 1 "\[tool.poetry.group.auth-controller.dependencies\]" pyproject.toml | awk -F '"' '{printf $$4}'))
$(eval WORKFLOW_REVISION := $(shell uv run python -c 'import tomllib; d=tomllib.load(open("pyproject.toml","rb")); s=d.get("tool",{}).get("uv",{}).get("sources",{}).get("workflows-logic",{}); print(s.get("tag") or s.get("rev") or "")'))
$(eval AUTH_CONTROLLER_REVISION := $(shell uv run python -c 'import tomllib; d=tomllib.load(open("pyproject.toml","rb")); s=d.get("tool",{}).get("uv",{}).get("sources",{}).get("auth-controller",{}); print(s.get("tag") or s.get("rev") or "")'))

git clone https://github.com/flagsmith/flagsmith-saml --depth 1 --branch ${SAML_REVISION} && mv ./flagsmith-saml/tests tests/saml_tests
git clone https://github.com/flagsmith/flagsmith-rbac --depth 1 --branch ${RBAC_REVISION} && mv ./flagsmith-rbac/tests tests/rbac_tests
Expand All @@ -164,13 +164,13 @@ integrate-private-tests:

.PHONY: generate-docs
generate-docs: generate-flagsmith-sdk-openapi
poetry run flagsmith docgen metrics > ../docs/docs/deployment-self-hosting/observability/_metrics-catalogue.md
poetry run flagsmith docgen events > ../docs/docs/deployment-self-hosting/observability/_events-catalogue.md
uv run flagsmith docgen metrics > ../docs/docs/deployment-self-hosting/observability/_metrics-catalogue.md
uv run flagsmith docgen events > ../docs/docs/deployment-self-hosting/observability/_events-catalogue.md

.PHONY: add-known-sdk-version
add-known-sdk-version:
poetry run python scripts/add-known-sdk-version.py $(opts)
uv run python scripts/add-known-sdk-version.py $(opts)

.PHONY: generate-mcp-spec
generate-mcp-spec:
poetry run python manage.py spectacular --generator-class api.openapi.MCPSchemaGenerator --file mcp_openapi.yaml
uv run python manage.py spectacular --generator-class api.openapi.MCPSchemaGenerator --file mcp_openapi.yaml
Loading
Loading