Skip to content

Commit 4374729

Browse files
committed
feat: improve gh sync configuration UI
* added back CodebaseReleaseFsApi get_sip_list_url and get_originals_list_url helpers. I'm not entire sure why these got removed
1 parent f14ae26 commit 4374729

File tree

13 files changed

+363
-283
lines changed

13 files changed

+363
-283
lines changed

django/library/fs.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,26 @@ def get_stage_storage(self, stage: StagingDirectories):
468468
else:
469469
raise ValueError(f"StageDirectories values {stage} not valid")
470470

471+
def get_sip_list_url(self, category: FileCategories):
472+
return reverse(
473+
"library:codebaserelease-sip-files-list",
474+
kwargs={
475+
"identifier": str(self.identifier),
476+
"version_number": self.version_number,
477+
"category": category.name,
478+
},
479+
)
480+
481+
def get_originals_list_url(self, category: FileCategories):
482+
return reverse(
483+
"library:codebaserelease-original-files-list",
484+
kwargs={
485+
"identifier": str(self.identifier),
486+
"version_number": self.version_number,
487+
"category": category.name,
488+
},
489+
)
490+
471491
def get_absolute_url(self, category: FileCategories, relpath: Path):
472492
return reverse(
473493
"library:codebaserelease-original-files-detail",

django/library/github_integration.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ def _import_package_and_metadata(self, release) -> bool:
417417
return self.log_success()
418418

419419
def extract_semver(self, value) -> str | None:
420+
if len(value) > 1024: # prevent expensive/malicious inputs
421+
return None
420422
match = re.search(r"v?(\d+\.\d+\.\d+)", value)
421423
return match.group(1) if match else None
422424

django/library/jinja2/library/codebases/git.jinja

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
{% block introduction %}
77
{% with github_config=settings("library.GitHubSyncConfiguration", use_default_site=True) %}
8-
<h1>GitHub Sync{% if github_config.is_beta %} <span class="beta-badge border-white text-white ms-1">Beta</span>{% endif %}</h1>
8+
<h1>GitHub Sync{% if github_config.is_beta %} <span class="beta-badge border-white text-white ms-1">Beta</span>{% endif
9+
%}</h1>
910
{% endwith %}
1011
{% endblock %}
1112

@@ -18,26 +19,17 @@
1819
<h1 class="codebase-title mb-3">
1920
Configure GitHub Sync for <i>{{ codebase.title }}</i>
2021
</h1>
21-
<p>
22-
GitHub Sync allows you to connect your model in the CoMSES Model Library (CML) to a GitHub
22+
<p class="text-muted">
23+
GitHub Sync allows you to connect your model in the CoMSES Model Library to a GitHub
2324
repository.
2425
</p>
2526
<p>
26-
When creating a new repository here, a git repo will be automatically built from the public
27-
releases of your model and <b><u>pushed</u> to GitHub</b>. This will be updated every time you
28-
publish a new release or update the metadata of an existing one, until it is disabled.
29-
</p>
30-
<p>
31-
Changes made to synced repositories on GitHub can be automically pulled back into the CML by
32-
enabling <b><u>importing</u> from GitHub</b> and creating a new release on GitHub. This works
33-
similarly to the <i>Zenodo</i> GitHub integration.
34-
</p>
35-
<p>
36-
<a href="{{ url('library:github-sync-overview') }}">Learn more about how it works <i class="fas fa-chevron-right"></i></a>
27+
<a href="{{ url('library:github-sync-overview') }}">Learn more about how it works <i
28+
class="fas fa-chevron-right"></i></a>
3729
</p>
38-
<hr />
39-
<div class='my-3' id="github-sync" data-codebase-identifier="{{ codebase.identifier }}" data-is-codebase-live="{{ codebase.live }}"
40-
data-github-org-name="{{ github_org_name }}" data-default-repo-name="{{ slugify(codebase.title) }}"></div>
30+
<div class='my-3' id="github-sync" data-codebase-identifier="{{ codebase.identifier }}"
31+
data-is-codebase-live="{{ codebase.live }}" data-github-org-name="{{ github_org_name }}"
32+
data-default-repo-name="{{ slugify(codebase.title) }}"></div>
4133
{% endblock %}
4234

4335
{% block js %}

django/library/tests/test_fs.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ def test_repo_build(self):
117117
api = CodebaseGitRepositoryApi(self.codebase)
118118
api.build()
119119
# check that the mirror model is updated and the repo is built
120-
self.assertIsNotNone(self.git_mirror.last_local_update)
121-
self.assertEqual(self.git_mirror.local_releases.count(), 1)
120+
self.assertIsNotNone(self.git_mirror.last_modified)
121+
self.assertEqual(self.git_mirror.built_releases.count(), 1)
122122
self.assertTrue(os.path.exists(api.repo_dir))
123123
# check git stuff
124124
repo = Repo(api.repo_dir)
@@ -153,7 +153,7 @@ def test_repo_append_releases(self):
153153
self.release_2.publish()
154154
api.append_releases()
155155

156-
self.assertEqual(self.git_mirror.local_releases.count(), 2)
156+
self.assertEqual(self.git_mirror.built_releases.count(), 2)
157157
# check git stuff
158158
repo = Repo(api.repo_dir)
159159
self.assertFalse(repo.is_dirty())
@@ -204,7 +204,7 @@ def test_repo_rebuild(self):
204204
self.release_2.publish()
205205
api.build()
206206

207-
self.assertEqual(self.git_mirror.local_releases.count(), 2)
207+
self.assertEqual(self.git_mirror.built_releases.count(), 2)
208208
# check git stuff
209209
repo = Repo(api.repo_dir)
210210
self.assertFalse(repo.is_dirty())

django/library/views.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,8 @@ def setup_user_github_remote(self, request, *args, **kwargs):
710710
validator.validate_format()
711711
validator.check_user_repo_empty(installation)
712712
except ValueError as e:
713-
raise ValidationError(str(e))
713+
error_message = e.args[0] if e.args else "Invalid repository configuration"
714+
raise ValidationError(error_message)
714715

715716
# create a mirror if it doesn't exist
716717
if not codebase.git_mirror:
@@ -752,7 +753,8 @@ def setup_user_existing_github_remote(self, request, *args, **kwargs):
752753
validator.validate_format()
753754
repo_html_url = validator.get_existing_user_repo_url(installation)
754755
except ValueError as e:
755-
raise ValidationError(str(e))
756+
error_message = e.args[0] if e.args else "Invalid repository configuration"
757+
raise ValidationError(error_message)
756758

757759
# create a mirror if it doesn't exist
758760
if not codebase.git_mirror:
@@ -790,7 +792,8 @@ def setup_org_github_remote(self, request, *args, **kwargs):
790792
validator.validate_format()
791793
validator.check_org_repo_name_unused()
792794
except ValueError as e:
793-
raise ValidationError(str(e))
795+
error_message = e.args[0] if e.args else "Invalid repository configuration"
796+
raise ValidationError(error_message)
794797

795798
# create a mirror if it doesn't exist
796799
if not codebase.git_mirror:
@@ -1351,6 +1354,9 @@ def get_queryset(self):
13511354
queryset = self.queryset.filter(codebase__identifier=identifier)
13521355
return queryset.accessible(user=self.request.user)
13531356

1357+
def get_list_url(self, api):
1358+
raise NotImplementedError
1359+
13541360
def get_category(self) -> FileCategories:
13551361
category = self.get_parser_context(self.request)["kwargs"]["category"]
13561362
try:
@@ -1397,6 +1403,9 @@ def get_object(self, queryset=None):
13971403
class CodebaseReleaseFilesSipViewSet(BaseCodebaseReleaseFilesViewSet):
13981404
stage = StagingDirectories.sip
13991405

1406+
def get_list_url(self, api):
1407+
return api.get_sip_list_url
1408+
14001409
@action(detail=False, methods=["post"])
14011410
def update_category(self, request, **kwargs):
14021411
"""update a file's category, currently only for imported releases
@@ -1422,13 +1431,17 @@ def update_category(self, request, **kwargs):
14221431
try:
14231432
fs_api.manifest.update_file_category(file_path, new_category)
14241433
except ValueError as e:
1425-
raise ValidationError(str(e))
1434+
error_message = e.args[0] if e.args else "Unable to update file category"
1435+
raise ValidationError(error_message)
14261436
return Response(status=status.HTTP_200_OK)
14271437

14281438

14291439
class CodebaseReleaseFilesOriginalsViewSet(BaseCodebaseReleaseFilesViewSet):
14301440
stage = StagingDirectories.originals
14311441

1442+
def get_list_url(self, api):
1443+
return api.get_originals_list_url
1444+
14321445
def create(self, request, *args, **kwargs):
14331446
codebase_release = self.get_object()
14341447
fs_api = codebase_release.get_fs_api()
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<template>
2+
<div class="card mb-3">
3+
<div class="card-header p-3 bg-dark text-white">
4+
<h5 class="mb-0">Sync requirements</h5>
5+
</div>
6+
<div class="d-flex flex-column h-100">
7+
<div class="list-group list-group-flush">
8+
<div class="list-group-item p-3">
9+
<i v-if="!githubAccount" class="fas fa-times-circle text-danger me-2"></i>
10+
<i v-else class="fas fa-check-circle text-success me-2"></i>
11+
<span v-if="!githubAccount">GitHub account <u>not connected</u></span>
12+
<span v-else>
13+
Connected as
14+
<a :href="githubAccount.profileUrl" target="_blank" class="badge bg-dark">
15+
<i class="fab fa-github me-1"></i>
16+
{{ githubAccount.username }}
17+
</a>
18+
</span>
19+
</div>
20+
<div class="list-group-item p-3 border-bottom">
21+
<i v-if="!githubAppInstalled" class="fas fa-times-circle text-danger me-2"></i>
22+
<i v-else class="fas fa-check-circle text-success me-2"></i>
23+
CoMSES Sync App
24+
<u v-if="!githubAppInstalled">not installed</u>
25+
<u v-else>installed</u>
26+
<p v-if="!githubAppInstalled && githubAccount" class="small text-muted mb-0 mt-1">
27+
<small
28+
>Installed but not recognized? Try refreshing the page or
29+
<a :href="installationStatus.installationUrl || ''" target="_blank"
30+
>uninstalling and reinstalling the app</a
31+
>.
32+
</small>
33+
</p>
34+
</div>
35+
</div>
36+
<div class="flex-grow-1 d-flex justify-content-center align-items-center p-3">
37+
<a v-if="!githubAccount" :href="installationStatus.connectUrl" class="btn btn-secondary">
38+
<i class="fab fa-github me-2"></i>
39+
Connect GitHub
40+
</a>
41+
<a
42+
v-else-if="!githubAppInstalled"
43+
:href="installationStatus.installationUrl || ''"
44+
target="_blank"
45+
class="btn btn-primary"
46+
>
47+
<i class="fas fa-download me-2"></i>
48+
Install App
49+
</a>
50+
<a
51+
v-else
52+
:href="installationStatus.installationUrl || ''"
53+
target="_blank"
54+
class="btn btn-outline-secondary"
55+
>
56+
<i class="fas fa-cog me-2"></i>
57+
Manage Installation
58+
</a>
59+
</div>
60+
</div>
61+
</div>
62+
</template>
63+
64+
<script setup lang="ts">
65+
import { computed } from "vue";
66+
import type { GitHubAppInstallationStatus } from "@/types";
67+
68+
const props = defineProps<{
69+
installationStatus: GitHubAppInstallationStatus;
70+
}>();
71+
72+
const githubAccount = computed(() => props.installationStatus.githubAccount);
73+
const githubAppInstalled = computed(() => !!githubAccount.value?.installationId);
74+
</script>

frontend/src/components/GitHubRemoteItem.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="d-flex align-items-center justify-content-between">
3-
<div class="d-flex flex-column align-items-start">
3+
<div class="d-flex flex-column align-items-start flex-grow-1 me-3">
44
<a :href="remote.url" target="_blank">
55
<i class="fab fa-github"></i>
66
{{ remote.owner }}/{{ remote.repoName }}
@@ -13,7 +13,7 @@
1313
</small>
1414
</button>
1515
</div>
16-
<div class="d-flex">
16+
<div class="d-flex flex-row flex-shrink-0 gap-3">
1717
<div v-if="!remote.isPreexisting" class="form-check form-switch me-3">
1818
<input
1919
class="form-check-input"
@@ -24,7 +24,7 @@
2424
/>
2525
<label class="form-check-label" for="flexSwitchCheckDefault">Pushing</label>
2626
<div>
27-
<small class="form-text text-muted"
27+
<small class="form-text text-muted text-nowrap"
2828
><small><i class="fas fa-code-branch"></i> to GitHub</small></small
2929
>
3030
</div>
@@ -39,7 +39,7 @@
3939
/>
4040
<label class="form-check-label" for="flexSwitchCheckDefault1">Importing</label>
4141
<div>
42-
<small class="form-text text-muted"
42+
<small class="form-text text-muted text-nowrap"
4343
><small><i class="fas fa-archive"></i> from GitHub</small></small
4444
>
4545
</div>

frontend/src/components/GitHubSetupOrgRemoteWizard.vue

Lines changed: 0 additions & 75 deletions
This file was deleted.

0 commit comments

Comments
 (0)