Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a9c5b67
feat: add huey for async task processing
sgfost Jan 9, 2025
f5233a6
build: dynamically add vue apps to vite config
sgfost Jan 9, 2025
4dc1e7f
feat: add codemeta_snapshot field and license text
sgfost Jan 9, 2025
7885432
refactor: standardize definition of 'author' contributors
sgfost Jan 9, 2025
7622cef
refactor: use codemeticulous and on save hook for metadata generation
sgfost Jan 9, 2025
f0bda6a
refactor: datacite generation from codemeta
sgfost Jan 10, 2025
1f4dd64
refactor: replace json.loads(obj.json()) idiom
sgfost Jan 10, 2025
9cbc597
fix: properly transform output data url to codemeta
sgfost Jan 13, 2025
b6d93cd
test: disable test_codemeta, add test_metadata
sgfost Jan 16, 2025
4a571d5
feat: add model for tracking git mirror of a codebase
sgfost Jan 9, 2025
5fc7484
feat: add codebase git repository fs api
sgfost Jan 9, 2025
c109dd5
feat: add github integration api and mirroring tasks
sgfost Jan 9, 2025
c1b51d4
feat: github integration ui and mirroring feature
sgfost Jan 9, 2025
d3432cb
feat: rework git integration models and github/fs apis
sgfost Jan 25, 2025
5fae340
feat: views/routing for github integration config
sgfost Jan 28, 2025
49ef397
feat: add github sync configuration page
sgfost Jan 29, 2025
595a3dd
feat: add create/update functionality to the gh sync config
sgfost Jan 29, 2025
ac85a4b
feat: add guidance for connecting acct in gh sync config
sgfost Jan 30, 2025
bb48dca
feat: add new feature overview/explainer page for gh sync
sgfost Jan 30, 2025
38036fa
feat: add external/archived release type
sgfost Feb 4, 2025
cc8ad74
feat(WIP): user-owned repos webhook + workflows
sgfost Feb 7, 2025
e873d41
feat: user-owned repos are working
sgfost Feb 7, 2025
0ee9eae
feat: remove github sync org option, refine UI and overview/help page
sgfost Feb 12, 2025
8c05280
fix: rename github -> CML process 'archiving' -> 'importing'
sgfost Feb 13, 2025
fd8b095
fix: improve syncing workflow and transparency
sgfost Feb 14, 2025
f3b298d
feat(WIP): github release importing
sgfost Feb 21, 2025
d4f6fb3
feat(WIP): add release FS API for imported releases
sgfost Mar 5, 2025
d1ce604
feat: github release importing
sgfost Mar 7, 2025
5717645
feat: imported-specific release editor UI
sgfost Mar 19, 2025
2235b0e
feat: extract metadata from imported releases to populate CML release
sgfost Mar 21, 2025
d00c9b3
fix: add configurable github app webhook secret
sgfost Mar 27, 2025
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SECRETS_DIR=${BUILD_DIR}/secrets
DB_PASSWORD_PATH=${SECRETS_DIR}/db_password
PGPASS_PATH=${SECRETS_DIR}/.pgpass
SECRET_KEY_PATH=${SECRETS_DIR}/django_secret_key
EXT_SECRETS=hcaptcha_secret github_client_secret orcid_client_secret discourse_api_key discourse_sso_secret mail_api_key datacite_api_password
EXT_SECRETS=hcaptcha_secret github_client_secret orcid_client_secret discourse_api_key discourse_sso_secret mail_api_key datacite_api_password github_integration_app_private_key github_integration_app_webhook_secret
GENERATED_SECRETS=$(DB_PASSWORD_PATH) $(PGPASS_PATH) $(SECRET_KEY_PATH)

ENVREPLACE := deploy/scripts/envreplace
Expand Down
6 changes: 6 additions & 0 deletions base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ services:
- django_secret_key
- github_client_secret
- orcid_client_secret
- github_integration_app_private_key
- github_integration_app_webhook_secret
- hcaptcha_secret
- mail_api_key
volumes:
Expand Down Expand Up @@ -98,6 +100,10 @@ secrets:
file: ./build/secrets/django_secret_key
github_client_secret:
file: ./build/secrets/github_client_secret
github_integration_app_private_key:
file: ./build/secrets/github_integration_app_private_key
github_integration_app_webhook_secret:
file: ./build/secrets/github_integration_app_webhook_secret
hcaptcha_secret:
file: ./build/secrets/hcaptcha_secret
mail_api_key:
Expand Down
6 changes: 6 additions & 0 deletions deploy/conf/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ ORCID_CLIENT_ID=
DATACITE_API_USERNAME=
DATACITE_DRY_RUN="true" # allowed values: "true" or "false"

# github integration app
GITHUB_INTEGRATION_APP_ID=
GITHUB_INTEGRATION_APP_NAME=
GITHUB_INTEGRATION_APP_INSTALLATION_ID=
GITHUB_MODEL_LIBRARY_ORG_NAME=

# test
TEST_USER_ID=10000000
TEST_USERNAME=__test_user__
Expand Down
14 changes: 11 additions & 3 deletions django/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ RUN --mount=type=cache,target=/var/lib/apt,sharing=locked \
&& update-alternatives --install /usr/bin/python python /usr/bin/python3 1000 \
&& python -m venv ${VIRTUAL_ENV} \
&& apt-get upgrade -q -y -o Dpkg::Options::="--force-confold" \
&& mkdir -p /etc/service/django \
&& touch /etc/service/django/run /etc/postgresql-backup-pre \
&& chmod a+x /etc/service/django/run /etc/postgresql-backup-pre \
&& mkdir -p /etc/service/django /etc/service/huey \
&& touch /etc/service/django/run /etc/service/huey/run /etc/postgresql-backup-pre \
&& chmod a+x /etc/service/django/run /etc/service/huey/run /etc/postgresql-backup-pre \
&& apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /code
Expand All @@ -61,5 +61,13 @@ COPY ./deploy/cron.weekly/* /etc/cron.weekly/
COPY ./deploy/db/autopostgresqlbackup.conf /etc/default/autopostgresqlbackup
COPY ./deploy/db/postgresql-backup-pre /etc/
COPY ${RUN_SCRIPT} /etc/service/django/run
COPY ./deploy/huey.sh /etc/service/huey/run
COPY . /code

# FIXME: replace with install from pypi
# upgrading pip because of some bug with the debian patched version
RUN python3 -m pip install --upgrade pip
RUN pip3 install git+https://github.com/sgfost/codemeticulous.git
RUN pip3 install -r /tmp/requirements.txt

CMD ["/sbin/my_init"]
13 changes: 13 additions & 0 deletions django/core/huey.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django_redis import get_redis_connection
from huey import RedisHuey


class DjangoRedisHuey(RedisHuey):
"""Huey subclass that uses the existing connection pool
from the django-redis cache backend
"""

def __init__(self, *args, **kwargs):
connection = get_redis_connection("default")
kwargs["connection_pool"] = connection.connection_pool
super().__init__(*args, **kwargs)
8 changes: 8 additions & 0 deletions django/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,14 @@ def github_url(self):
"""
return self.get_social_account_profile_url("github")

@property
def github_username(self):
github_account = self.get_social_account("github")
if github_account:
return github_account.extra_data.get("login")
else:
return None

def get_social_account_profile_url(self, provider_name):
social_acct = self.get_social_account(provider_name)
if social_acct:
Expand Down
4 changes: 1 addition & 3 deletions django/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,8 @@ def create(model_cls, validated_data, context):

def update(serializer_update, instance, validated_data):
tags = TagSerializer(many=True, data=validated_data.pop("tags"))
instance = serializer_update(instance, validated_data)
set_tags(instance, tags)
instance.save()
return instance
return serializer_update(instance, validated_data)


class EditableSerializerMixin(serializers.Serializer):
Expand Down
29 changes: 27 additions & 2 deletions django/core/settings/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def is_test(self):
"django_extensions",
"django_vite",
"guardian",
"huey.contrib.djhuey",
"rest_framework",
"rest_framework_swagger",
"robots",
Expand Down Expand Up @@ -396,6 +397,11 @@ def is_test(self):
"handlers": ["console", "comsesfile"],
"propagate": False,
},
"huey": {
"level": "INFO",
"handlers": ["console", "comsesfile"],
"propagate": False,
},
},
}

Expand Down Expand Up @@ -479,10 +485,19 @@ def is_test(self):
"LOCATION": "unix:///shared/redis/redis.sock",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 20},
},
}
}

HUEY = {
"name": "comses",
"huey_class": "core.huey.DjangoRedisHuey",
"immediate": False, # always run tasks in the background (for now), if removed it will default to DEBUG
# FIXME: this should generally be True in development, the huey consumer WILL NOT
# automatically reload when the code changes when False
}

# SSO, user registration, and django-allauth configuration, see
# https://django-allauth.readthedocs.io/en/latest/configuration.html
# ACCOUNT_ADAPTER = 'core.adapter.AccountAdapter'
Expand All @@ -501,12 +516,22 @@ def is_test(self):
ACCOUNT_CHANGE_EMAIL = True

ORCID_CLIENT_ID = os.getenv("ORCID_CLIENT_ID", "")

ORCID_CLIENT_SECRET = read_secret("orcid_client_secret")

GITHUB_CLIENT_ID = os.getenv("GITHUB_CLIENT_ID", "")
GITHUB_CLIENT_SECRET = read_secret("github_client_secret")

GITHUB_INTEGRATION_APP_ID = int(os.getenv("GITHUB_INTEGRATION_APP_ID") or 0)
GITHUB_INTEGRATION_APP_NAME = os.getenv("GITHUB_INTEGRATION_APP_NAME", "")
GITHUB_INTEGRATION_APP_PRIVATE_KEY = read_secret("github_integration_app_private_key")
GITHUB_INTEGRATION_APP_INSTALLATION_ID = int(
os.getenv("GITHUB_INTEGRATION_APP_INSTALLATION_ID") or 0
)
GITHUB_INTEGRATION_APP_WEBHOOK_SECRET = read_secret("github_integration_app_webhook_secret")
GITHUB_MODEL_LIBRARY_ORG_NAME = os.getenv("GITHUB_MODEL_LIBRARY_ORG_NAME", "")
GITHUB_INDIVIDUAL_FILE_SIZE_LIMIT = os.getenv(
"GITHUB_INDIVIDUAL_FILE_SIZE_LIMIT", 100 * 1024 * 1024
)

TEST_BASIC_AUTH_PASSWORD = os.getenv("TEST_BASIC_AUTH_PASSWORD", "test password")
TEST_USER_ID = os.getenv("TEST_USER_ID", 1000000)
TEST_USERNAME = os.getenv("TEST_USERNAME", "__test_user__")
Expand Down
2 changes: 1 addition & 1 deletion django/core/settings/e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
SHARE_DIR = path.realpath("/shared/e2e")
LIBRARY_ROOT = path.join(SHARE_DIR, "library")
LIBRARY_PREVIOUS_ROOT = path.join(SHARE_DIR, ".latest")
REPOSITORY_ROOT = path.join(BASE_DIR, "repository")
REPOSITORY_ROOT = path.join(SHARE_DIR, "repository")
BACKUP_ROOT = path.join(SHARE_DIR, "backups")
BORG_ROOT = path.join(BACKUP_ROOT, "repo")
EXTRACT_ROOT = path.join(SHARE_DIR, "extract")
Expand Down
5 changes: 5 additions & 0 deletions django/core/settings/staging.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,10 @@
"handlers": ["comsesfile"],
"propagate": False,
},
"huey": {
"level": "WARNING",
"handlers": ["comsesfile"],
"propagate": False,
},
},
}
2 changes: 1 addition & 1 deletion django/core/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
SHARE_DIR = path.realpath("library/tests/tmp")
LIBRARY_ROOT = path.join(SHARE_DIR, "library")
LIBRARY_PREVIOUS_ROOT = path.join(SHARE_DIR, ".latest")
REPOSITORY_ROOT = path.join(BASE_DIR, "repository")
REPOSITORY_ROOT = path.join(SHARE_DIR, "repository")
BACKUP_ROOT = path.join(SHARE_DIR, "backups")
BORG_ROOT = path.join(BACKUP_ROOT, "repo")
EXTRACT_ROOT = path.join(SHARE_DIR, "extract")
Expand Down
8 changes: 8 additions & 0 deletions django/core/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,13 @@ def initialize_test_shared_folders():
)


def clear_test_shared_folder(dir=settings.REPOSITORY_ROOT):
for fs in os.scandir(dir):
if fs.is_dir():
shutil.rmtree(os.path.join(dir, fs.name), ignore_errors=True)
elif fs.is_file():
os.remove(os.path.join(dir, fs.name))


def destroy_test_shared_folders():
shutil.rmtree(settings.SHARE_DIR, ignore_errors=True)
2 changes: 2 additions & 0 deletions django/curator/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
def fsck(queryset):
results = OrderedDict()
for release in queryset:
if release.is_imported:
continue
rfsc = CodebaseReleaseFileConsistencyChecker(release)
errors = rfsc.check()
if errors:
Expand Down
4 changes: 2 additions & 2 deletions django/curator/tests/test_dump_restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from core.tests.base import EventFactory, JobFactory
from library.fs import import_archive
from library.models import Codebase
from library.tests.base import CodebaseFactory
from library.tests.base import CodebaseFactory, TEST_SAMPLES_DIR

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -51,7 +51,7 @@ def setUp(self):
fs_api = self.release.get_fs_api()
import_archive(
codebase_release=self.release,
nested_code_folder_name="library/tests/archives/nestedcode",
nested_code_folder_name=TEST_SAMPLES_DIR / "archives" / "nestedcode",
fs_api=fs_api,
)

Expand Down
2 changes: 2 additions & 0 deletions django/deploy/huey.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
exec /code/manage.py run_huey
Loading