Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,25 @@ permissions:
jobs:
lint:
name: Run Lint
uses: codecov/gha-workflows/.github/workflows/[email protected].26
uses: codecov/gha-workflows/.github/workflows/[email protected].33

build:
name: Build API
uses: codecov/gha-workflows/.github/workflows/[email protected].26
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit
with:
repo: ${{ vars.CODECOV_IMAGE_V2 || 'codecov/self-hosted-api' }}

codecovstartup:
name: Codecov Startup
needs: build
uses: codecov/gha-workflows/.github/workflows/[email protected].26
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit

test:
name: Test
needs: [build]
uses: codecov/gha-workflows/.github/workflows/[email protected].30
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit
with:
run_integration: false
Expand All @@ -48,7 +48,7 @@ jobs:
build-self-hosted:
name: Build Self Hosted API
needs: [build, test]
uses: codecov/gha-workflows/.github/workflows/[email protected].27
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit
with:
repo: ${{ vars.CODECOV_IMAGE_V2 || 'codecov/self-hosted-api' }}
Expand All @@ -57,7 +57,7 @@ jobs:
name: Push Staging Image
needs: [build, test]
if: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/staging' && github.repository_owner == 'codecov' }}
uses: codecov/gha-workflows/.github/workflows/[email protected].27
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit
with:
environment: staging
Expand All @@ -67,7 +67,7 @@ jobs:
name: Push Production Image
needs: [build, test]
if: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/main' && github.repository_owner == 'codecov' }}
uses: codecov/gha-workflows/.github/workflows/[email protected].27
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit
with:
environment: production
Expand All @@ -78,7 +78,7 @@ jobs:
needs: [build-self-hosted, test]
secrets: inherit
if: ${{ github.event_name == 'push' && github.event.ref == 'refs/heads/main' && github.repository_owner == 'codecov' }}
uses: codecov/gha-workflows/.github/workflows/[email protected].27
uses: codecov/gha-workflows/.github/workflows/[email protected].33
with:
push_rolling: true
repo: ${{ vars.CODECOV_IMAGE_V2 || 'codecov/self-hosted-api' }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also might need a cache_file param for this self-hosted workflow to pick the uv.lock file to hash.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in f9f2257

2 changes: 1 addition & 1 deletion .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ on:
jobs:
patch-typing-check:
name: Run Patch Type Check
uses: codecov/gha-workflows/.github/workflows/[email protected].21
uses: codecov/gha-workflows/.github/workflows/[email protected].33
2 changes: 1 addition & 1 deletion .github/workflows/self-hosted-release-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ on:
jobs:
create-release-pr:
name: Create PR for Release ${{ github.event.inputs.versionName }}
uses: codecov/gha-workflows/.github/workflows/[email protected].21
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit
4 changes: 2 additions & 2 deletions .github/workflows/self-hosted-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ jobs:
create-release:
name: Tag Release ${{ github.head_ref }} and Push Docker image to Docker Hub
if: ${{ github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/') && github.repository_owner == 'codecov' }}
uses: codecov/gha-workflows/.github/workflows/[email protected].21
uses: codecov/gha-workflows/.github/workflows/[email protected].33
with:
tag_to_prepend: self-hosted-
secrets: inherit

push-image:
needs: [create-release]
if: ${{ github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/') && github.repository_owner == 'codecov' }}
uses: codecov/gha-workflows/.github/workflows/[email protected].21
uses: codecov/gha-workflows/.github/workflows/[email protected].33
secrets: inherit
with:
push_release: true
Expand Down
34 changes: 17 additions & 17 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ branch = $(shell git branch | grep \* | cut -f2 -d' ')
epoch := $(shell date +"%s")
AR_REPO ?= codecov/api
DOCKERHUB_REPO ?= codecov/self-hosted-api
REQUIREMENTS_TAG := requirements-v1-$(shell sha1sum requirements.txt | cut -d ' ' -f 1)-$(shell sha1sum docker/Dockerfile.requirements | cut -d ' ' -f 1)
REQUIREMENTS_TAG := requirements-v1-$(shell sha1sum uv.lock | cut -d ' ' -f 1)-$(shell sha1sum docker/Dockerfile.requirements | cut -d ' ' -f 1)
VERSION := release-${sha}
CODECOV_UPLOAD_TOKEN ?= "notset"
CODECOV_STATIC_TOKEN ?= "notset"
Expand All @@ -21,7 +21,7 @@ API_DOMAIN ?= api
PROXY_NETWORK ?= api_default

# Codecov CLI version to use
CODECOV_CLI_VERSION := 0.5.1
CODECOV_CLI_VERSION := 9.0.4

build:
make build.requirements
Expand All @@ -31,20 +31,20 @@ check-for-migration-conflicts:
python manage.py check_for_migration_conflicts

test:
COVERAGE_CORE=sysmon python -m pytest --cov=./ --junitxml=junit.xml -o junit_family=legacy
COVERAGE_CORE=sysmon pytest --cov=./ --junitxml=junit.xml -o junit_family=legacy

test.unit:
@if [ -n "$(GROUP)" ]; then \
COVERAGE_CORE=sysmon python -m pytest --splits ${SPLIT} --group $(GROUP) --cov=./ -m "not integration" --cov-report=xml:unit.$(GROUP).coverage.xml --junitxml=unit.$(GROUP).junit.xml -o junit_family=legacy; \
COVERAGE_CORE=sysmon pytest --splits ${SPLIT} --group $(GROUP) --cov=./ -m "not integration" --cov-report=xml:unit.$(GROUP).coverage.xml --junitxml=unit.$(GROUP).junit.xml -o junit_family=legacy; \
else \
COVERAGE_CORE=sysmon python -m pytest --cov=./ -m "not integration" --cov-report=xml:unit.coverage.xml --junitxml=unit.junit.xml -o junit_family=legacy; \
COVERAGE_CORE=sysmon pytest --cov=./ -m "not integration" --cov-report=xml:unit.coverage.xml --junitxml=unit.junit.xml -o junit_family=legacy; \
fi

test.integration:
@if [ -n "$(GROUP)" ]; then \
COVERAGE_CORE=sysmon python -m pytest --splits ${SPLIT} --group $(GROUP) --cov=./ -m "integration" --cov-report=xml:integration.$(GROUP).coverage.xml --junitxml=integration.$(GROUP).junit.xml -o junit_family=legacy; \
COVERAGE_CORE=sysmon pytest --splits ${SPLIT} --group $(GROUP) --cov=./ -m "integration" --cov-report=xml:integration.$(GROUP).coverage.xml --junitxml=integration.$(GROUP).junit.xml -o junit_family=legacy; \
else \
COVERAGE_CORE=sysmon python -m pytest --cov=./ -m "integration" --cov-report=xml:integration.coverage.xml --junitxml=integration.junit.xml -o junit_family=legacy; \
COVERAGE_CORE=sysmon pytest --cov=./ -m "integration" --cov-report=xml:integration.coverage.xml --junitxml=integration.junit.xml -o junit_family=legacy; \
fi

lint:
Expand All @@ -53,7 +53,7 @@ lint:

lint.install:
echo "Installing..."
pip install -Iv ruff
uv add --dev ruff

lint.run:
ruff check
Expand Down Expand Up @@ -187,17 +187,17 @@ push.self-hosted-rolling:
docker push ${DOCKERHUB_REPO}:rolling

shell:
docker-compose exec api bash
docker compose exec api bash

test_env.up:
env | grep GITHUB > .testenv; true
TIMESERIES_ENABLED=${TIMESERIES_ENABLED} docker-compose up -d
TIMESERIES_ENABLED=${TIMESERIES_ENABLED} docker compose up -d

test_env.prepare:
docker-compose exec api make test_env.container_prepare
docker compose exec api make test_env.container_prepare

test_env.check_db:
docker-compose exec api make test_env.container_check_db
docker compose exec api make test_env.container_check_db
make test_env.check-for-migration-conflicts

test_env.install_cli:
Expand All @@ -213,21 +213,21 @@ test_env.container_check_db:

test_env.run_unit:
@if [ -n "$(GROUP)" ]; then \
docker-compose exec api make test.unit SPLIT=${SPLIT} GROUP=${GROUP}; \
docker compose exec api make test.unit SPLIT=${SPLIT} GROUP=${GROUP}; \
else \
docker-compose exec api make test.unit; \
docker compose exec api make test.unit; \
fi

test_env.run_integration:
# @if [ -n "$(GROUP)" ]; then \
# docker-compose exec api make test.integration SPLIT=${SPLIT} GROUP=${GROUP}; \
# docker compose exec api make test.integration SPLIT=${SPLIT} GROUP=${GROUP}; \
# else \
# docker-compose exec api make test.integration; \
# docker compose exec api make test.integration; \
# fi
echo "Skipping. No Tests"

test_env.check-for-migration-conflicts:
docker-compose exec api python manage.py check_for_migration_conflicts
docker compose exec api python manage.py check_for_migration_conflicts

test_env:
make test_env.up
Expand Down
22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
Codecov API
-----------
## Codecov API

> We believe that everyone should have access to quality software (like Sentry), that’s why we have always offered Codecov for free to open source maintainers.
>
> By making our code public, we’re not only joining the community that’s supported us from the start — but also want to make sure that every developer can contribute to and build on the Codecov experience.

A private Django REST Framework API intended to serve Codecov's front end.
A private Django REST Framework API intended to serve Codecov's front end.

## Getting Started

Expand All @@ -21,7 +20,7 @@ Note, you'll need to install Rust to build `ribs` which is a dependency of `shar

### Running Standalone

This project contains a `docker-compose.yml` file that is intended to run the api standalone. In this configuration it **does not** share codecov.io's development database; so don't expect parity there.
This project contains a `docker-compose.yml` file that is intended to run the api standalone. In this configuration it **does not** share codecov.io's development database; so don't expect parity there.

To start the service, do

Expand All @@ -33,7 +32,7 @@ Once running, the api will be available at `http://localhost:5100`

### Running with codecov.io

This service will startup when you run codecov.io normally. It is under that `api` block of codecov.io's `docker-compose.yml` file.
This service will startup when you run codecov.io normally. It is under that `api` block of codecov.io's `docker-compose.yml` file.

### Testing

Expand All @@ -48,7 +47,7 @@ If you would like to use pytest directly (Either through an IDE like PyCharm or

RUN_ENV=TESTING DJANGO_SETTINGS_MODULE=codecov.settings_test pytest

Make sure to have all the requirements from `requirements.txt` installed.
Make sure to have all the latest dependencies installed via `uv sync`.

### Deploying

Expand All @@ -69,17 +68,12 @@ Steps 2 and 3 are important to limit interaction between features not yet merged
This project should store no secrets or credentials in its source. If you need to add to / modify / setup secrets for this project, contact Eli and he'll get you started..

### Adding dependencies
This repository uses `pip-tools` to manage dependencies, so make sure you've installed it with `pip install pip-tools`. To add or update dependencies, change `requirements.in`, Then run

```
pip-compile requirements.in
```

Do not change `requirements.txt` directly.
This repository uses `uv` to manage dependencies, so make sure you've installed it with `pip install uv`. To add or update dependencies, simply run `uv add __package_name__` or `uv sync`.

### Formatting

This project uses `ruff` for formatting.
This project uses `ruff` for formatting.
You can run the linter using the command `make lint`.

### Migrations
Expand All @@ -88,4 +82,4 @@ We leverage Django's migration system to keep the state of our models in sync wi

## Contributing

This repository, like all of Codecov's repositories, strives to follow our general [Contributing guidlines](https://github.com/codecov/contributing). If you're considering making a contribution to this repository, we encourage review of our Contributing guidelines first.
This repository, like all of Codecov's repositories, strives to follow our general [Contributing guidlines](https://github.com/codecov/contributing). If you're considering making a contribution to this repository, we encourage review of our Contributing guidelines first.
3 changes: 2 additions & 1 deletion dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ _start_gunicorn() {
python manage.py insert_data_to_db_from_csv core/management/commands/codecovPlans-Jan25.csv --model plans
fi
if [[ "$DEBUGPY" ]]; then
pip install debugpy
uv add debugpy
uv sync
python -m debugpy --listen 0.0.0.0:12345 -m gunicorn codecov.wsgi:application --reload --bind 0.0.0.0:8000 --access-logfile '-' --timeout "${GUNICORN_TIMEOUT:-600}" $suffix
fi
gunicorn codecov.wsgi:application --reload --bind 0.0.0.0:8000 --access-logfile '-' --timeout "${GUNICORN_TIMEOUT:-600}" $suffix
Expand Down
9 changes: 4 additions & 5 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ ARG BERGLAS_VERSION=2.0.6
FROM us-docker.pkg.dev/berglas/berglas/berglas:$BERGLAS_VERSION as berglas

FROM $REQUIREMENTS_IMAGE as app
COPY . /app

WORKDIR /app
RUN pip install setuptools==71.1.0
RUN python manage.py collectstatic --no-input
ADD . /app
# RUN python manage.py collectstatic --no-input

FROM app as local

Expand All @@ -20,7 +20,6 @@ COPY --chmod=755 --from=berglas /bin/berglas /usr/local/bin/berglas

FROM app as self-hosted

RUN pip uninstall -y typing
# set settings module
ENV DJANGO_SETTINGS_MODULE="codecov.settings_enterprise"
# Remove the settings dev and enterprise files.
Expand Down Expand Up @@ -57,7 +56,7 @@ FROM self-hosted as self-hosted-runtime
USER root
ARG EXTERNAL_DEPS_FOLDER=./external_deps
RUN mkdir $EXTERNAL_DEPS_FOLDER
RUN pip install --target $EXTERNAL_DEPS_FOLDER psycopg2-binary tlslite-ng
RUN uv add --target $EXTERNAL_DEPS_FOLDER psycopg2-binary tlslite-ng
RUN chown codecov:application $EXTERNAL_DEPS_FOLDER
USER codecov

Expand Down
47 changes: 35 additions & 12 deletions docker/Dockerfile.requirements
Original file line number Diff line number Diff line change
@@ -1,34 +1,57 @@
# syntax=docker/dockerfile:1.4
ARG PYTHON_IMAGE=python:3.12-slim-bookworm
ARG PYTHON_IMAGE=ghcr.io/astral-sh/uv:python3.12-bookworm-slim

# BUILD STAGE - Download dependencies from GitHub that require SSH access
FROM $PYTHON_IMAGE as build

RUN apt-get update
RUN apt-get install -y \
curl \
git \
build-essential \
libffi-dev \
libpq-dev \
curl
libpq-dev

ENV UV_LINK_MODE=copy \
UV_COMPILE_BYTECODE=1 \
UV_PYTHON_DOWNLOADS=never \
UV_PYTHON=python \
UV_PROJECT_ENVIRONMENT=/api

# Then, add the rest of the project source code and install it
# Installing separately from its dependencies allows optimal layer caching
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv export --no-hashes --frozen --format requirements-txt > requirements.txt

COPY requirements.txt /
WORKDIR /pip-packages/
RUN pip wheel -r /requirements.txt
RUN rm -rf /pip-packages/src

RUN grep -v '^-e ' requirements.txt > requirements.remote.txt
# build all remote wheels
RUN pip wheel -w wheels --find-links wheels -r requirements.remote.txt

# build all local packages to wheels
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv build --all-packages --wheel -o wheels

# RUNTIME STAGE - Copy packages from build stage and install runtime dependencies
FROM $PYTHON_IMAGE

# Our postgres driver psycopg2 requires libpq-dev as a runtime dependency
RUN apt-get update
RUN apt-get install -y \
git \
libpq-dev \
make \
curl \
libexpat1 \
&& pip install --upgrade pip
libexpat1

COPY --from=build /wheels/ /wheels/

WORKDIR /pip-packages/
COPY --from=build /pip-packages/ /pip-packages/
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv pip install --no-deps --no-index --find-links=wheels wheels/* --system

RUN pip install --no-deps --no-index --find-links=/pip-packages/ /pip-packages/*
Loading
Loading