Skip to content

Commit

Permalink
Merge pull request #597 from UW-GAC/deploy/stage
Browse files Browse the repository at this point in the history
Deploy to prod
  • Loading branch information
amstilp authored Jun 3, 2024
2 parents c0f87ea + e95bd24 commit 7b996b4
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 40 deletions.
46 changes: 37 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ jobs:
backend: ["sqlite", "mariadb"]
mariadb-version: ["10.4"]
include:
- python-version: 3.8 # Possible future version.
- python-version: 3.12 # Possible future version.
backend: "mariadb"
mariadb-version: "10.5"
pip-recompile: true
- python-version: 3.12 # Possible future version.
backend: "mariadb"
mariadb-version: "10.11"
pip-recompile: true

name: "py${{ matrix.python-version }}-${{ matrix.backend }}-${{ matrix.mariadb-version }}"

services:
Expand Down Expand Up @@ -63,23 +69,44 @@ jobs:
requirements/requirements.txt
requirements/test-requirements.txt
- name: Install Dependencies
- name: Ensure pip is installed
run: |
python -m ensurepip --upgrade
python -m pip install --upgrade pip
pip install pip-tools
# Upgrade setup tools
python -m pip install --upgrade setuptools
- name: Install piptools
run: python -m pip install pip-tools

- name: Recompile pip files if requested
if: matrix.pip-recompile
run: |
pip-compile requirements/requirements.in
pip-compile requirements/test-requirements.in
# Print out changes.
git diff
- name: Install Dependencies
run: |
pip-sync requirements/requirements.txt requirements/test-requirements.txt
- name: Collect staticfiles
run: python manage.py collectstatic --noinput --settings=config.settings.test

- name: Run tests
run: coverage run -p -m pytest
run: |
pytest --cov=primed -n auto
mv .coverage .coverage-${{ strategy.job-index }}
- name: List files for debugging purposes
run: ls -lhta

- name: Upload coverage data
uses: actions/upload-artifact@v4
with:
name: coverage-data-${{ strategy.job-index }}
path: .coverage.*
path: .coverage-${{ strategy.job-index }}

coverage:
needs:
Expand All @@ -106,13 +133,14 @@ jobs:

- name: Merge coverage files
run: |
mv ./artifacts/coverage-data*/.coverage* .
python -m coverage combine ./artifacts/coverage-data*/.coverage-*
python -m coverage xml
ls -la .coverage*
- name: Combine coverage data
- name: Report coverage
run: |
python -m coverage combine
python -m coverage xml
python -m coverage report
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/pip-compile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Update pip-tools requirements files
on:
pull_request:
branches: [ "main" ]


jobs:
update-requirements-files:
runs-on: ubuntu-latest

steps:
- name: Checkout Code Repository
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}

- name: Set up Python 3.8
uses: actions/setup-python@v5
with:
python-version: 3.8

- name: Update requirements files
uses: UW-GAC/pip-tools-actions/[email protected]
with:
requirements_files: |-
requirements/requirements.in
requirements/test-requirements.in
requirements/dev-requirements.in
pr-title: Update requirements file for ${{ github.head_ref }}
pr-branch-suffix: "${{ github.event.number}}"
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ fail_fast: true

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.2
rev: v0.4.7
hooks:
# Run the linter.
- id: ruff
Expand All @@ -21,7 +21,7 @@ repos:
- id: ruff-format

- repo: https://github.com/gitleaks/gitleaks
rev: v8.16.1
rev: v8.18.3
hooks:
- id: gitleaks

Expand Down
4 changes: 4 additions & 0 deletions add_dbgap_example_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
dbgap_dac="NHLBI",
dbgap_current_status=models.dbGaPDataAccessRequest.REJECTED,
)
dar_1_5 = factories.dbGaPDataAccessRequestFactory(
dbgap_data_access_snapshot=dar_snapshot_1,
dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED,
)

dbgap_application_2 = factories.dbGaPApplicationFactory.create(
principal_investigator=UserFactory.create(name="Alisa", username="Alisa"),
Expand Down
6 changes: 6 additions & 0 deletions primed/dbgap/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,9 @@ def get_dbgap_workspaces(self):
dbgap_consent_code=self.dbgap_consent_code,
).order_by("dbgap_version")
return dbgap_workspaces

def get_matching_studies(self):
"""Get the list of studies matching dbGaP study accession phs associated with this data access request."""

study_list = Study.objects.filter(dbgapstudyaccession__dbgap_phs=self.dbgap_phs)
return study_list
10 changes: 10 additions & 0 deletions primed/dbgap/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@ class dbGaPDataAccessRequestBySnapshotTable(dbGaPDataAccessRequestTable):
dbgap_data_access_snapshot__dbgap_application__dbgap_project_id = None
dbgap_data_access_snapshot__created = None
matching_workspaces = tables.columns.Column(accessor="get_dbgap_workspaces", orderable=False, default=" ")
matching_studies = tables.columns.ManyToManyColumn(
accessor="get_matching_studies",
verbose_name="Studies",
linkify_item=True,
)

class Meta:
model = models.dbGaPDataAccessRequest
Expand All @@ -273,6 +278,11 @@ class Meta:
)
order_by = ("dbgap_dar_id",)
attrs = {"class": "table table-sm"}
sequence = (
"dbgap_dar_id",
"dbgap_dac",
"matching_studies",
)

def render_matching_workspaces(self, value, record):
template_code = """
Expand Down
6 changes: 1 addition & 5 deletions primed/dbgap/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,14 @@ class Meta:
model = models.dbGaPDataAccessRequest


class dbGaPDataAccessRequestForWorkspaceFactory(DjangoModelFactory):
class dbGaPDataAccessRequestForWorkspaceFactory(dbGaPDataAccessRequestFactory):
"""A factory for the dbGaPApplication model to match a workspace."""

dbgap_data_access_snapshot = SubFactory(dbGaPDataAccessSnapshotFactory)
dbgap_phs = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_study_accession.dbgap_phs)
dbgap_dar_id = Sequence(lambda n: n + 1)
original_version = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_version)
original_participant_set = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_participant_set)
dbgap_consent_code = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_consent_code)
dbgap_consent_abbreviation = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_consent_abbreviation)
dbgap_current_status = models.dbGaPDataAccessRequest.APPROVED
dbgap_dac = Faker("word")

class Params:
dbgap_workspace = None
Expand Down
28 changes: 28 additions & 0 deletions primed/dbgap/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1525,3 +1525,31 @@ def test_get_dbgap_link(self):
"""`get_dbgab_link` returns a link."""
instance = factories.dbGaPDataAccessRequestFactory.create()
self.assertIsInstance(instance.get_dbgap_link(), str)

def test_get_studies_no_matches(self):
"""Returns an empty queryset when there is no matching studies."""
factories.dbGaPStudyAccessionFactory.create()
dar = factories.dbGaPDataAccessRequestFactory.create()
self.assertEqual(dar.get_matching_studies().count(), 0)

def test_get_studies_one_match(self):
"""Returns the correct study when there is one match."""
test_study = StudyFactory.create(short_name="Test", full_name="Test Study")
dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=1, studies=[test_study])
dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs)
qs = dar.get_matching_studies()
self.assertEqual(qs.count(), 1)
self.assertEqual(qs[0], test_study)

def test_get_studies_two_match(self):
"""Returns the correct studies when there are 2 match."""
test_study_1 = StudyFactory.create(short_name="Test 1", full_name="Test Study 1")
test_study_2 = StudyFactory.create(short_name="Test 2", full_name="Test Study 2")
dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create(
dbgap_phs=1, studies=[test_study_1, test_study_2]
)
dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs)
qs = dar.get_matching_studies()
self.assertEqual(qs.count(), 2)
self.assertEqual(qs[0], test_study_1)
self.assertEqual(qs[1], test_study_2)
20 changes: 20 additions & 0 deletions primed/dbgap/tests/test_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,26 @@ def test_ordering(self):
self.assertEqual(table.data[0], instance_2)
self.assertEqual(table.data[1], instance_1)

def test_one_matching_study(self):
"""Table works if there is a matching study"""
test_study = factories.StudyFactory.create(short_name="Test", full_name="Test Study")
dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=1, studies=[test_study])
dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs)
table = self.table_class([dar])
self.assertIn(test_study.short_name, table.rows[0].get_cell("matching_studies"))

def test_two_matching_studies(self):
"""Table works if there is are two matching studies"""
test_study_1 = factories.StudyFactory.create(short_name="Test 1", full_name="Test Study 1")
test_study_2 = factories.StudyFactory.create(short_name="Test 2", full_name="Test Study 2")
dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create(
dbgap_phs=1, studies=[test_study_1, test_study_2]
)
dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs)
table = self.table_class([dar])
self.assertIn(test_study_1.short_name, table.rows[0].get_cell("matching_studies"))
self.assertIn(test_study_2.short_name, table.rows[0].get_cell("matching_studies"))


class dbGaPDataAccessRequestSummaryTable(TestCase):
model = models.dbGaPDataAccessRequest
Expand Down
8 changes: 4 additions & 4 deletions primed/dbgap/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2141,17 +2141,17 @@ def test_error_missing_json(self):

def test_get_dbgap_application_pk_does_not_exist(self):
"""Raises a 404 error with an invalid object dbgap_application_pk."""
request = self.factory.get(self.get_url(self.dbgap_application.pk + 1))
request = self.factory.get(self.get_url(self.dbgap_application.pk + 999))
request.user = self.user
with self.assertRaises(Http404):
self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 1)
self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 999)

def test_post_dbgap_application_pk_does_not_exist(self):
"""Raises a 404 error with an invalid object dbgap_application_pk."""
request = self.factory.post(self.get_url(self.dbgap_application.pk + 1), {})
request = self.factory.post(self.get_url(self.dbgap_application.pk + 999), {})
request.user = self.user
with self.assertRaises(Http404):
self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 1)
self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 999)

def test_has_form_when_one_snapshot_exists(self):
phs_int = fake.random_int()
Expand Down
2 changes: 1 addition & 1 deletion primed/drupal_oauth_provider/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def get_mocked_response(self):
# This login response mimics drupals in that it contains a set of scopes
# and the uid which has the name sub
def get_login_response_json(self, with_refresh_token=True):
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.timezone.utc)
app = get_adapter().get_app(request=None, provider=self.provider_id)
allowed_audience = app.client_id
id_token = sign_id_token(
Expand Down
3 changes: 2 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[pytest]
addopts = --ds=config.settings.test --reuse-db
addopts = --ds=config.settings.test --reuse-db -n auto
python_files = tests.py test_*.py
filterwarnings =
# Convert all warnings to errors.
Expand All @@ -8,3 +8,4 @@ filterwarnings =
ignore:pkg_resources is deprecated as an API.:DeprecationWarning:model_utils
# Warning raised by pkg_resources via model_utils. ??
ignore:Deprecated call to `pkg_resources.declare_namespace:DeprecationWarning:pkg_resources
ignore:'pkgutil.find_loader' is deprecated and slated for removal in Python 3.14:DeprecationWarning
2 changes: 1 addition & 1 deletion requirements/dev-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ipdb # https://github.com/gotcha/ipdb
# Type checking
# ------------------------------------------------------------------------------
mypy # https://github.com/python/mypy
django-stubs # https://github.com/typeddjango/django-stubs
django-stubs>=4.2,<5.0 # https://github.com/typeddjango/django-stubs
types-requests

# Documentation
Expand Down
12 changes: 6 additions & 6 deletions requirements/dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ decorator==5.1.1
# ipython
distlib==0.3.8
# via virtualenv
django==4.2.11
django==4.2.13
# via
# -c requirements/requirements.txt
# django-debug-toolbar
# django-stubs
# django-stubs-ext
django-debug-toolbar==4.3.0
django-debug-toolbar==4.4.2
# via -r requirements/dev-requirements.in
django-stubs==4.2.7
# via -r requirements/dev-requirements.in
Expand Down Expand Up @@ -77,7 +77,7 @@ ipython==8.12.3
# via ipdb
jedi==0.19.1
# via ipython
jinja2==3.1.3
jinja2==3.1.4
# via sphinx
livereload==2.6.3
# via sphinx-autobuild
Expand Down Expand Up @@ -136,7 +136,7 @@ requests==2.31.0
# -c requirements/requirements.txt
# -c requirements/test-requirements.txt
# sphinx
ruff==0.4.2
ruff==0.4.7
# via -r requirements/dev-requirements.in
six==1.16.0
# via
Expand Down Expand Up @@ -188,7 +188,7 @@ types-pytz==2024.1.0.20240203
# via django-stubs
types-pyyaml==6.0.12.12
# via django-stubs
types-requests==2.31.0.20240406
types-requests==2.32.0.20240602
# via -r requirements/dev-requirements.in
typing-extensions==4.8.0
# via
Expand All @@ -209,7 +209,7 @@ virtualenv==20.25.1
# via pre-commit
wcwidth==0.2.13
# via prompt-toolkit
werkzeug==3.0.2
werkzeug==3.0.3
# via -r requirements/dev-requirements.in
zipp==3.17.0
# via
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ django-dbbackup # https://github.com/jazzband/django-dbbackup
django-extensions # https://github.com/django-extensions/django-extensions

# anvil_consortium_manager
django-anvil-consortium-manager @ git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.22
django-anvil-consortium-manager @ git+https://github.com/UW-GAC/django-anvil-consortium-manager.git@v0.23

# Simple history - model history tracking
django-simple-history
Expand Down
Loading

0 comments on commit 7b996b4

Please sign in to comment.