Skip to content

Commit

Permalink
Merge pull request #4805 from opensafely-core/release-file-reuploads
Browse files Browse the repository at this point in the history
Allow release file reuploads to different workspaces
  • Loading branch information
rebkwok authored Jan 14, 2025
2 parents 8d88faf + d3912b6 commit 4e777a4
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
9 changes: 5 additions & 4 deletions jobserver/releases.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,24 @@ def build_outputs_zip(release_files, url_builder_func):
return in_memory_zf


def check_not_already_uploaded(filename, filehash, backend):
"""Check if this filename/filehash combination has been uploaded before."""
def check_not_already_uploaded(workspace, filename, filehash, backend):
"""Check if this workspace/filename/filehash combination has been uploaded before."""
duplicate = ReleaseFile.objects.filter(
release__backend=backend,
workspace=workspace,
name=filename,
filehash=filehash,
)
if duplicate.exists():
raise ReleaseFileAlreadyExists(
f"This version of '{filename}' has already been uploaded from backend '{backend.slug}'"
f"This version of '{filename}' in workspace {workspace} has already been uploaded from backend '{backend.slug}'"
)


@transaction.atomic
def create_release(workspace, backend, created_by, requested_files, **kwargs):
for f in requested_files:
check_not_already_uploaded(f["name"], f["sha256"], backend)
check_not_already_uploaded(workspace, f["name"], f["sha256"], backend)

release = Release.objects.create(
workspace=workspace,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/jobserver/api/test_releases.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,10 +818,10 @@ def test_releaseworkspaceapi_post_create_release_with_oversized_file(

def test_releaseworkspaceapi_post_release_already_exists(api_rf, project_membership):
user = UserFactory(roles=[OutputChecker])

release = ReleaseFactory()
rfile = ReleaseFileFactory(
release=release,
workspace=release.workspace,
created_by=user,
name="file.txt",
filehash="hash",
Expand Down
38 changes: 35 additions & 3 deletions tests/unit/jobserver/test_releases.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ def test_build_outputs_zip_with_missing_files(build_release_with_files):


def test_create_release_reupload():
rfile = ReleaseFileFactory(name="file1.txt", filehash="hash")
workspace = WorkspaceFactory(name="workspace")
rfile = ReleaseFileFactory(workspace=workspace, name="file1.txt", filehash="hash")

files = [
{
Expand All @@ -93,20 +94,51 @@ def test_create_release_reupload():
"url": "",
"size": 4,
"sha256": "hash",
"mtime": "2022-08-17T13:37Z",
"date": "2022-08-17T13:37Z",
"metadata": {},
}
]

with pytest.raises(releases.ReleaseFileAlreadyExists):
releases.create_release(
rfile.release.workspace,
workspace,
rfile.release.backend,
rfile.release.created_by,
files,
)


def test_create_release_reupload_to_different_workspace():
workspace = WorkspaceFactory(name="workspace")
another_workspace = WorkspaceFactory(name="another_workspace")
rfile = ReleaseFileFactory(workspace=workspace, name="file1.txt", filehash="hash")

files = [
{
"name": "file1.txt",
"path": "path/to/file1.txt",
"url": "",
"size": 4,
"sha256": "hash",
"date": "2022-08-17T13:37Z",
"metadata": {},
}
]

release = releases.create_release(
another_workspace,
rfile.release.backend,
rfile.release.created_by,
files,
)
assert release.requested_files == files
assert release.files.count() == 1

rfile = release.files.first()
rfile.filehash == "hash"
rfile.size == 4


def test_create_release_success():
backend = BackendFactory()
workspace = WorkspaceFactory()
Expand Down

0 comments on commit 4e777a4

Please sign in to comment.