Skip to content
Open
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
29 changes: 29 additions & 0 deletions .github/actions/codeartifact-login/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CodeArtifact login
description: Assume the staging CodeArtifact role via OIDC, fetch an authorisation token, and export Poetry HTTP basic auth env vars

outputs:
token:
description: CodeArtifact authorisation token
value: ${{ steps.codeartifact.outputs.token }}

runs:
using: composite
steps:
- name: Configure AWS credentials for CodeArtifact
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::302456015006:role/codeartifact-github-actions-staging
aws-region: eu-west-2

- name: Fetch CodeArtifact authorisation token
id: codeartifact
shell: bash
run: |
token=$(aws codeartifact get-authorization-token \
--domain flagsmith-staging \
--domain-owner 302456015006 \
--query authorizationToken --output text)
echo "::add-mask::$token"
echo "token=$token" >> "$GITHUB_OUTPUT"
echo "POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_USERNAME=aws" >> "$GITHUB_ENV"
echo "POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_PASSWORD=$token" >> "$GITHUB_ENV"
8 changes: 7 additions & 1 deletion .github/workflows/.reusable-docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Authenticate with CodeArtifact
id: codeartifact
uses: ./.github/actions/codeartifact-login

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
Expand All @@ -113,7 +117,9 @@ jobs:
save: ${{ inputs.ephemeral }}
push: ${{ !inputs.ephemeral }}
platforms: linux/amd64,linux/arm64
secrets: ${{ secrets.secrets }}
secrets: |
${{ secrets.secrets }}
codeartifact_token=${{ steps.codeartifact.outputs.token }}
target: ${{ inputs.target }}
build-args: |
CI_COMMIT_SHA=${{ github.sha }}
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/api-deploy-production-ecs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
needs: deploy-ecs
name: Push MCP Schema to Gram
runs-on: depot-ubuntu-latest
permissions:
contents: read
id-token: write # For CodeArtifact OIDC
defaults:
run:
working-directory: api
Expand All @@ -39,6 +42,9 @@ jobs:
python-version: "3.12"
cache: poetry

- name: Authenticate with CodeArtifact
uses: ./.github/actions/codeartifact-login

- name: Install dependencies
run: |
echo "https://${{ secrets.GH_PRIVATE_ACCESS_TOKEN }}:@github.com" > ${HOME}/.git-credentials
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/api-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: API Pull Request

permissions:
contents: read # For actions/checkout
id-token: write # For Codecov OIDC
id-token: write # For Codecov and CodeArtifact OIDC

on:
pull_request:
Expand Down Expand Up @@ -50,6 +50,9 @@ jobs:
python-version: ${{ matrix.python-version }}
cache: poetry

- name: Authenticate with CodeArtifact
uses: ./.github/actions/codeartifact-login

- name: Install Dependencies
run: make install-packages

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/api-run-makefile-target.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ on:
permissions:
contents: write
pull-requests: write
id-token: write # For CodeArtifact OIDC

defaults:
run:
Expand All @@ -41,6 +42,9 @@ jobs:
python-version: 3.13
cache: poetry

- name: Authenticate with CodeArtifact
uses: ./.github/actions/codeartifact-login

- name: Install Dependencies
run: make install-packages

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/api-tests-with-private-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: API Pull Request with Private Packages

permissions:
contents: read # For actions/checkout
id-token: write # For Codecov OIDC
id-token: write # For Codecov and CodeArtifact OIDC

on:
pull_request:
Expand Down Expand Up @@ -51,6 +51,9 @@ jobs:
- name: Install SAML Dependencies
run: sudo apt-get install -y xmlsec1

- name: Authenticate with CodeArtifact
uses: ./.github/actions/codeartifact-login

- name: Install packages and Tests
shell: bash
run: |
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/update-flagsmith-environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ defaults:
run:
working-directory: api

permissions:
contents: read
id-token: write # For CodeArtifact OIDC

jobs:
update_server_defaults:
runs-on: depot-ubuntu-latest
Expand All @@ -26,6 +30,9 @@ jobs:
python-version: 3.12
cache: pip

- name: Authenticate with CodeArtifact
uses: ./.github/actions/codeartifact-login

- name: Install Dependencies
run: make install

Expand Down
35 changes: 29 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@

# Build an Open Source Unified image:
# (`oss-unified` stage is the default one, so there's no need to specify a target stage)
# $ docker build -t flagsmith:dev .
# $ CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token \
# --domain flagsmith-staging --domain-owner 302456015006 \
# --query authorizationToken --output text) \
# docker build -t flagsmith:dev \
# --secret="id=codeartifact_token,env=CODEARTIFACT_TOKEN" .

# Build a SaaS API image:
# $ GH_TOKEN=$(gh auth token) docker build -t flagsmith-saas-api:dev --target saas-api \
# --secret="id=sse_pgp_pkey,src=./sse_pgp_pkey.key"\
# --secret="id=github_private_cloud_token,env=GH_TOKEN" .
# --secret="id=github_private_cloud_token,env=GH_TOKEN" \
# --secret="id=codeartifact_token,env=CODEARTIFACT_TOKEN" .

# Build a Private Cloud Unified image:
# $ GH_TOKEN=$(gh auth token) docker build -t flagsmith-private-cloud:dev --target private-cloud-unified \
# --secret="id=github_private_cloud_token,env=GH_TOKEN" .
# --secret="id=github_private_cloud_token,env=GH_TOKEN" \
# --secret="id=codeartifact_token,env=CODEARTIFACT_TOKEN" .

# `codeartifact_token` is required for any target that runs `poetry install`,
# since the `flagsmith-sql-flag-engine` dep is hosted on Flagsmith's
# private CodeArtifact PyPI. See the `[[tool.poetry.source]]` block in
# `api/pyproject.toml`.

# Table of Contents
# Stages are described as stage-name [dependencies]
Expand Down Expand Up @@ -100,7 +111,10 @@ ENV POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_VIRTUALENVS_OPTIONS_NO_SETUPTOOLS=true \
POETRY_HOME=/opt/poetry \
PATH="/opt/poetry/bin:$PATH"
RUN make install opts='--without dev'
RUN --mount=type=secret,id=codeartifact_token \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_USERNAME=aws \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_PASSWORD="$(cat /run/secrets/codeartifact_token)" \
make install opts='--without dev'

# * build-python-private [build-python]
FROM build-python AS build-python-private
Expand All @@ -111,8 +125,11 @@ ARG SAML_REVISION
ARG RBAC_REVISION
ARG WITH="saml,auth-controller,ldap,workflows,licensing,release-pipelines"
RUN --mount=type=secret,id=github_private_cloud_token \
--mount=type=secret,id=codeartifact_token \
echo "https://$(cat /run/secrets/github_private_cloud_token):@github.com" > ${HOME}/.git-credentials && \
git config --global credential.helper store && \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_USERNAME=aws \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_PASSWORD="$(cat /run/secrets/codeartifact_token)" \
make install-packages opts='--without dev --with ${WITH}' && \
make install-private-modules

Expand Down Expand Up @@ -161,7 +178,10 @@ FROM build-python AS api-test

COPY api /build/

RUN make install-packages opts='--with dev'
RUN --mount=type=secret,id=codeartifact_token \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_USERNAME=aws \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_PASSWORD="$(cat /run/secrets/codeartifact_token)" \
make install-packages opts='--with dev'

CMD ["make", "test"]

Expand All @@ -170,7 +190,10 @@ FROM build-python-private AS api-private-test

COPY api /build/

RUN make install-packages opts='--with dev' && \
RUN --mount=type=secret,id=codeartifact_token \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_USERNAME=aws \
POETRY_HTTP_BASIC_FLAGSMITH_PYPI_STAGING_PASSWORD="$(cat /run/secrets/codeartifact_token)" \
make install-packages opts='--with dev' && \
make integrate-private-tests && \
git config --global --unset credential.helper && \
rm -f ${HOME}/.git-credentials
Expand Down
14 changes: 14 additions & 0 deletions api/app/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
"features.workflows.core",
"features.release_pipelines.core",
"segments",
"segment_membership",
"app",
"e2etests",
"simple_history",
Expand Down Expand Up @@ -1429,3 +1430,16 @@
PYLON_IDENTITY_VERIFICATION_SECRET = env.str("PYLON_IDENTITY_VERIFICATION_SECRET", None)

OSIC_UPDATE_BATCH_SIZE = env.int("OSIC_UPDATE_BATCH_SIZE", default=500)

# --- Snowflake (segment membership inspection) -------------------------------
# All-None default disables the segment_membership backfill and refresh tasks.
# When set, the api/segments/membership tasks open a Snowpark session and run
# against this account. See docs/deployment/observability/segment-membership.md
# for the operational shape.
SNOWFLAKE_ACCOUNT = env.str("SNOWFLAKE_ACCOUNT", default=None)
SNOWFLAKE_USER = env.str("SNOWFLAKE_USER", default=None)
SNOWFLAKE_PRIVATE_KEY_PATH = env.str("SNOWFLAKE_PRIVATE_KEY_PATH", default=None)
SNOWFLAKE_ROLE = env.str("SNOWFLAKE_ROLE", default=None)
SNOWFLAKE_WAREHOUSE = env.str("SNOWFLAKE_WAREHOUSE", default=None)
SNOWFLAKE_DATABASE = env.str("SNOWFLAKE_DATABASE", default=None)
SNOWFLAKE_SCHEMA = env.str("SNOWFLAKE_SCHEMA", default=None)
Loading
Loading