Skip to content

Commit 41f9878

Browse files
committed
Merge branch 'feature/pbs-25-13' of https://github.com/CenterForOpenScience/osf.io into add-has-data-annotations-to-linked-nodes
* 'feature/pbs-25-13' of https://github.com/CenterForOpenScience/osf.io: (42 commits) [ENG-8462] Institution setup fixes (CenterForOpenScience#11241) [ENG-8401] Earlier preprint versions download the current file (CenterForOpenScience#11245) added academiaInstitution in social-schema, fixed True value of 'ongoing', fixed/added tests (CenterForOpenScience#11239) [ENG-7979] Registrations pending moderation that have components also pending moderation do not display the children (CenterForOpenScience#11222) [ENG-8216] Fixed children deletion on a node page in admin (CenterForOpenScience#11237) [ENG-8401] Fixed preprint downloading (CenterForOpenScience#11238) fix categories for sendgrid emails (CenterForOpenScience#11236) [ENG-8936] API: Allow /v2/users/me/preprints list view to filter by tags (CenterForOpenScience#11232) Add collections scopes to FULL_READ and FULL_WRITE add brand relationship to collectionprovider [ENG-8224] Fixed force archive template with registration addons (CenterForOpenScience#11210) API: Allow /v2/users/me/preprints list view to filter by title [ENG-8325] Public column does not display the visibility status of child nodes on the Nodes page in the Admin App [ENG-8246] Fixed deletion of maintenance alerts in admin (CenterForOpenScience#11226) add exception handling to /review_actions/ endpoint Update chagnelog and bump version [ENG-6835] VRL Project PR - BE (CenterForOpenScience#11204) Bump version no. Add CHANGELOG move CROSSREF_UNAVAILABLE_DELAY to settings.py handle and 5xx status code from crossref ...
2 parents 91f4eb8 + 8745da4 commit 41f9878

145 files changed

Lines changed: 3295 additions & 590 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.docker-compose.gv.env

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ POSTGRES_DB="gravyvalet"
99
SECRET_KEY="secret"
1010
PYTHONUNBUFFERED=1 # This when set to 0 will allow print statements to be visible in the Docker logs
1111
OSF_AUTH_COOKIE_NAME=osf
12+
SESSION_COOKIE_SECURE=false
13+
SESSION_COOKIE_HTTPONLY=true
14+
SESSION_COOKIE_SAMESITE=Lax
1215
OSF_SENSITIVE_DATA_SECRET="TrainglesAre5Squares"
1316
OSF_SENSITIVE_DATA_SALT="yusaltydough"
1417
DEBUG=1
15-
16-

.github/actions/gen-report/action.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ description: 'Generate test report from junit xml file'
33
runs:
44
using: "composite"
55
steps:
6+
- name: Archive code coverage results
7+
uses: actions/upload-artifact@v4
8+
with:
9+
name: ${{github.job}} HTML REPORT
10+
path: report.html
611
- name: Generate Report
7-
uses: dorny/test-reporter@v1
12+
uses: dorny/test-reporter@v2
813
if: success() || failure() # run this step even if previous step failed
914
with:
1015
name: ${{github.job}} REPORT # Name of the check run which will be created

.github/workflows/test-build.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
uses: actions/cache@v4
2222
with:
2323
path: ~/.cache
24-
key: reqs_${{ hashFiles('**/pyproject.toml') }}
24+
key: reqs_${{ hashFiles('poetry.lock') }}
2525
restore-keys: reqs
2626
- run: |
2727
mkdir -p ~/.cache/downloads
@@ -30,7 +30,7 @@ jobs:
3030
mkdir -p ~/.cache/testmon
3131
rm -rf node_modules ## TODO remove this later
3232
33-
addons:
33+
addons_and_admin:
3434
runs-on: ubuntu-22.04
3535
needs: build-cache
3636
permissions:
@@ -52,9 +52,9 @@ jobs:
5252
- uses: actions/checkout@v2
5353
- uses: ./.github/actions/start-build
5454
- name: Run tests
55-
run: poetry run python3 -m invoke test-ci-addons -n 1 --junit
55+
run: poetry run python3 -m invoke test-ci-addons --junit
5656
- name: Upload report
57-
if: (github.event_name != 'pull_request') && (success() || failure()) # run this step even if previous step failed
57+
if: (success() || failure()) # run this step even if previous step failed
5858
uses: ./.github/actions/gen-report
5959

6060
website:
@@ -79,9 +79,9 @@ jobs:
7979
- uses: actions/checkout@v2
8080
- uses: ./.github/actions/start-build
8181
- name: Run tests
82-
run: poetry run python3 -m invoke test-ci-website -n 1 --junit
82+
run: poetry run python3 -m invoke test-ci-website --junit
8383
- name: Upload report
84-
if: (github.event_name != 'pull_request') && (success() || failure()) # run this step even if previous step failed
84+
if: (success() || failure()) # run this step even if previous step failed
8585
uses: ./.github/actions/gen-report
8686

8787
api1_and_js:
@@ -108,9 +108,9 @@ jobs:
108108
- name: NVM & yarn install
109109
run: poetry run python3 -m invoke assets --dev
110110
- name: Run test
111-
run: poetry run python3 -m invoke test-ci-api1-and-js -n 1 --junit
111+
run: poetry run python3 -m invoke test-ci-api1-and-js --junit
112112
- name: Upload report
113-
if: (github.event_name != 'pull_request') && (success() || failure()) # run this step even if previous step failed
113+
if: (success() || failure()) # run this step even if previous step failed
114114
uses: ./.github/actions/gen-report
115115

116116
api2:
@@ -135,9 +135,9 @@ jobs:
135135
- uses: actions/checkout@v2
136136
- uses: ./.github/actions/start-build
137137
- name: Run tests
138-
run: poetry run python3 -m invoke test-ci-api2 -n 1 --junit
138+
run: poetry run python3 -m invoke test-ci-api2 --junit
139139
- name: Upload report
140-
if: (github.event_name != 'pull_request') && (success() || failure()) # run this step even if previous step failed
140+
if: (success() || failure()) # run this step even if previous step failed
141141
uses: ./.github/actions/gen-report
142142

143143
api3_and_osf:
@@ -163,7 +163,7 @@ jobs:
163163
- uses: actions/checkout@v2
164164
- uses: ./.github/actions/start-build
165165
- name: Run tests
166-
run: poetry run python3 -m invoke test-ci-api3-and-osf -n 1 --junit
166+
run: poetry run python3 -m invoke test-ci-api3-and-osf --junit
167167
- name: Upload report
168-
if: (github.event_name != 'pull_request') && (success() || failure()) # run this step even if previous step failed
168+
if: (success() || failure()) # run this step even if previous step failed
169169
uses: ./.github/actions/gen-report

CHANGELOG

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,35 @@
22

33
We follow the CalVer (https://calver.org/) versioning scheme: YY.MINOR.MICRO.
44

5+
25.12.0 (2025-07-08)
6+
====================
7+
8+
- Verified Resource Linking project release - BE
9+
- OSF support for GV session optimization
10+
- OSF node log for add-ons
11+
- CI improvements
12+
- Task routing fixes
13+
14+
15+
25.11.1 (2025-07-03)
16+
====================
17+
18+
- Hotfix to handle crossref's anticipated downtime
19+
20+
25.11.0 (2025-06-30)
21+
====================
22+
23+
- Crossref DOIs not minting with _v1, OSF is displaying DOI versions with _v1
24+
- When hamming a spammed user, preprints and registrations remain private
25+
- Fix emabrgoed registrations not becoming public after admin date change
26+
- Add v2 enpoint for alternative email confirmation
27+
- Make relationship on v2/nodes for collected_in
28+
- API V2: get action reviews request not listing latest preprint submit/withdraw requests
29+
- Add ability for admin app to change registry that a registration belongs to
30+
- Update to /nodes/<node-id> api
31+
- Subscription filtering not working correctly
32+
- API V2: Serialize registation resource attributes in Node Linked By Registrations list view and Node Linked Registrations list view
33+
534
25.10.0 (2025-06-11)
635
====================
736

addons/base/views.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,13 +1006,17 @@ def persistent_file_download(auth, **kwargs):
10061006
file = BaseFileNode.active.filter(_id=id_or_guid).first()
10071007
if not file:
10081008
guid = Guid.load(id_or_guid)
1009-
if guid:
1010-
file = guid.referent
1011-
else:
1009+
if not guid:
10121010
raise HTTPError(http_status.HTTP_404_NOT_FOUND, data={
10131011
'message_short': 'File Not Found',
10141012
'message_long': 'The requested file could not be found.'
10151013
})
1014+
1015+
file = guid.referent
1016+
if type(file) is Preprint:
1017+
referent, _ = Guid.load_referent(id_or_guid)
1018+
file = referent.primary_file
1019+
10161020
if not file.is_file:
10171021
raise HTTPError(http_status.HTTP_400_BAD_REQUEST, data={
10181022
'message_long': 'Downloading folders is not permitted.'

admin/institutions/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
re_path(r'^import/$', views.ImportInstitution.as_view(), name='import'),
1010
re_path(r'^(?P<institution_id>[0-9]+)/$', views.InstitutionDetail.as_view(), name='detail'),
1111
re_path(r'^(?P<institution_id>[0-9]+)/export/$', views.InstitutionExport.as_view(), name='export'),
12+
re_path(r'^(?P<institution_id>[0-9]+)/monthly_report/$', views.InstitutionMonthlyReporterDo.as_view(), name='monthly_report'),
1213
re_path(r'^(?P<institution_id>[0-9]+)/delete/$', views.DeleteInstitution.as_view(), name='delete'),
1314
re_path(r'^(?P<institution_id>[0-9]+)/deactivate/$', views.DeactivateInstitution.as_view(), name='deactivate'),
1415
re_path(r'^(?P<institution_id>[0-9]+)/reactivate/$', views.ReactivateInstitution.as_view(), name='reactivate'),

admin/institutions/views.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from dateutil.parser import isoparse
23

34
from django.contrib import messages
45
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -15,6 +16,9 @@
1516
from admin.base.forms import ImportFileForm
1617
from admin.institutions.forms import InstitutionForm, InstitutionalMetricsAdminRegisterForm
1718
from osf.models import Institution, Node, OSFUser
19+
from osf.metrics.utils import YearMonth
20+
from osf.metrics.reporters import AllMonthlyReporters
21+
from osf.management.commands.monthly_reporters_go import monthly_reporter_do
1822

1923

2024
class InstitutionList(PermissionRequiredMixin, ListView):
@@ -129,6 +133,38 @@ def get(self, request, *args, **kwargs):
129133
return response
130134

131135

136+
class InstitutionMonthlyReporterDo(PermissionRequiredMixin, View):
137+
permission_required = 'osf.view_institution'
138+
raise_exception = True
139+
140+
def post(self, request, *args, **kwargs):
141+
institution_id = self.kwargs.get('institution_id')
142+
try:
143+
institution = Institution.objects.get_all_institutions().get(id=institution_id)
144+
except Institution.DoesNotExist:
145+
raise Http404(f"Institution with id {institution_id} is not found or deactivated.")
146+
147+
monthly_report_date = request.POST.get('monthly_report_date', None)
148+
if monthly_report_date:
149+
try:
150+
monthly_report_date = isoparse(monthly_report_date).date()
151+
except ValueError as exc:
152+
messages.error(request, str(exc))
153+
return redirect('institutions:detail', institution_id=institution.id)
154+
else:
155+
messages.error(request, 'Report date cannot be none.')
156+
return redirect('institutions:detail', institution_id=institution.id)
157+
158+
monthly_reporter_do.apply_async(kwargs={
159+
'yearmonth': str(YearMonth.from_date(monthly_report_date)),
160+
'reporter_key': request.POST.get('monthly_reporter', None),
161+
'report_kwargs': {'institution_pk': institution.id},
162+
})
163+
164+
messages.success(request, 'Monthly reporter successfully went.')
165+
return redirect('institutions:detail', institution_id=institution.id)
166+
167+
132168
class CreateInstitution(PermissionRequiredMixin, CreateView):
133169
permission_required = 'osf.change_institution'
134170
raise_exception = True
@@ -141,6 +177,18 @@ def get_context_data(self, *args, **kwargs):
141177
kwargs['import_form'] = ImportFileForm()
142178
return super().get_context_data(*args, **kwargs)
143179

180+
def form_valid(self, form):
181+
response = super().form_valid(form)
182+
183+
# Make a report after Institution is created
184+
monthly_reporter_do.apply_async(kwargs={
185+
'yearmonth': str(YearMonth.from_date(self.object.created)),
186+
'reporter_key': AllMonthlyReporters.INSTITUTIONAL_SUMMARY.name,
187+
'report_kwargs': {'institution_pk': self.object.id},
188+
})
189+
190+
return response
191+
144192

145193
class InstitutionNodeList(PermissionRequiredMixin, ListView):
146194
template_name = 'institutions/node_list.html'

admin/maintenance/views.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from admin.maintenance.forms import MaintenanceForm
77

88
from django.shortcuts import redirect
9+
from django.urls import reverse_lazy
910
from django.forms.models import model_to_dict
1011
from django.views.generic import DeleteView, TemplateView
1112
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -15,11 +16,13 @@ class DeleteMaintenance(PermissionRequiredMixin, DeleteView):
1516
permission_required = 'osf.delete_maintenancestate'
1617
raise_exception = True
1718
template_name = 'maintenance/delete_maintenance.html'
19+
success_url = reverse_lazy('maintenance:display')
1820

1921
def get_object(self, queryset=None):
2022
return MaintenanceState.objects.first()
2123

22-
def delete(self, request, *args, **kwargs):
24+
def post(self, request, *args, **kwargs):
25+
super().post(request, *args, **kwargs)
2326
maintenance.unset_maintenance()
2427
return redirect('maintenance:display')
2528

admin/management/views.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ def post(self, request, *args, **kwargs):
130130
if report_date is not None
131131
else ''
132132
),
133+
reporter_key=request.POST.get('monthly_reporter', '')
133134
)
134135

135136
if errors:

admin/nodes/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,5 @@
4545
re_path(r'^(?P<guid>[a-z0-9]+)/remove_notifications/$', views.NodeRemoveNotificationView.as_view(), name='node-remove-notifications'),
4646
re_path(r'^(?P<guid>[a-z0-9]+)/update_moderation_state/$', views.NodeUpdateModerationStateView.as_view(), name='node-update-mod-state'),
4747
re_path(r'^(?P<guid>[a-z0-9]+)/resync_datacite/$', views.NodeResyncDataCiteView.as_view(), name='resync-datacite'),
48+
re_path(r'^(?P<guid>[a-z0-9]+)/revert/$', views.NodeRevertToDraft.as_view(), name='revert-to-draft'),
4849
]

0 commit comments

Comments
 (0)