From 612b407b31cb0491399ea60ade1c95c0e186e057 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 10:36:35 +0000
Subject: [PATCH 01/45] Removes sdist from dist creation
wheels (bdist) include the version: https://github.com/mtkennerly/dunamai/issues/23
---
.github/workflows/publish_testpypi.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index 6cafc3e..799c9ce 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -67,7 +67,7 @@ jobs:
- name: Create dist/
run: |
- python setup.py sdist bdist_wheel
+ python setup.py bdist_wheel
twine check dist/*
- name: Publish package to TestPyPI
From 7a3b1eb8ad5e6f525b8a1767cfcdd41da2f6c55a Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 10:47:37 +0000
Subject: [PATCH 02/45] Adds GHA trigger on PR
---
.github/workflows/publish_testpypi.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index 799c9ce..a4c1ead 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -16,6 +16,7 @@
name: Publish package to TestPyPI
on:
+ pull_request_target:
push:
branches:
- main
From 45d37a5cf654230c4d5bdd1bc1d35a1fc8d83624 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:01:14 +0000
Subject: [PATCH 03/45] Update publish_testpypi.yml
---
.github/workflows/publish_testpypi.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index a4c1ead..e8b22f6 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -16,7 +16,7 @@
name: Publish package to TestPyPI
on:
- pull_request_target:
+ pull_request:
push:
branches:
- main
From afdb564f12788aa49acc0e3fa69b9b43dd697afd Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:23:34 +0000
Subject: [PATCH 04/45] Test _dunamai.get_version()
Also uses Version.from_any_vcs instead of Version.from_git()
---
nii2dcm/_version.py | 5 ++++-
setup.py | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/nii2dcm/_version.py b/nii2dcm/_version.py
index b8bebde..b4c4465 100644
--- a/nii2dcm/_version.py
+++ b/nii2dcm/_version.py
@@ -1,2 +1,5 @@
+import dunamai as _dunamai
from dunamai import Version, Style
-__version__ = Version.from_git().serialize(metadata=False, style=Style.SemVer)
+__version__ = _dunamai.get_version(
+ "nii2dcm", third_choice=_dunamai.Version.from_any_vcs
+).serialize(metadata=False, style=Style.SemVer)
\ No newline at end of file
diff --git a/setup.py b/setup.py
index ce87831..9f8c9e7 100644
--- a/setup.py
+++ b/setup.py
@@ -3,5 +3,5 @@
setup(
name="nii2dcm",
- version=Version.from_git().serialize(metadata=False, style=Style.SemVer),
+ version=Version.from_any_vcs().serialize(metadata=False, style=Style.SemVer),
)
\ No newline at end of file
From a90cbc3fd55bf7ba18c2295c6a307904e474ea38 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:29:27 +0000
Subject: [PATCH 05/45] Removes Style.SemVer call during serialize
---
nii2dcm/_version.py | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/nii2dcm/_version.py b/nii2dcm/_version.py
index b4c4465..2e76428 100644
--- a/nii2dcm/_version.py
+++ b/nii2dcm/_version.py
@@ -1,5 +1,3 @@
import dunamai as _dunamai
from dunamai import Version, Style
-__version__ = _dunamai.get_version(
- "nii2dcm", third_choice=_dunamai.Version.from_any_vcs
-).serialize(metadata=False, style=Style.SemVer)
\ No newline at end of file
+__version__ = _dunamai.get_version("nii2dcm", third_choice=_dunamai.Version.from_any_vcs).serialize()
\ No newline at end of file
From 21ab3bf52a09024f73cedf7b8e7b0da899467eeb Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:39:38 +0000
Subject: [PATCH 06/45] Tidying
---
nii2dcm/_version.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/nii2dcm/_version.py b/nii2dcm/_version.py
index 2e76428..0699dbf 100644
--- a/nii2dcm/_version.py
+++ b/nii2dcm/_version.py
@@ -1,3 +1,2 @@
import dunamai as _dunamai
-from dunamai import Version, Style
__version__ = _dunamai.get_version("nii2dcm", third_choice=_dunamai.Version.from_any_vcs).serialize()
\ No newline at end of file
From f985a4661eaac6ecb9e29ffa3649b1e67b30c998 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:40:33 +0000
Subject: [PATCH 07/45] Changes -d/--dicom_type to list only currently
available DICOM types
---
nii2dcm/__main__.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/nii2dcm/__main__.py b/nii2dcm/__main__.py
index de57792..abd393e 100644
--- a/nii2dcm/__main__.py
+++ b/nii2dcm/__main__.py
@@ -23,7 +23,11 @@ def cli(args=None):
parser.add_argument("input_file", type=str, help="[.nii/.nii.gz] input NIfTI file")
parser.add_argument("output_dir", type=str, help="[directory] output DICOM path")
- parser.add_argument("-d", "--dicom_type", type=str, help="[string] type of DICOM. e.g. MR, CT, US, XR, etc.")
+ parser.add_argument(
+ "-d","--dicom_type",
+ type=str,
+ help="[string] type of DICOM. Available types: MR, SVR."
+ )
parser.add_argument("-r", "--ref_dicom", type=str, help="[.dcm] Reference DICOM file for Attribute transfer")
parser.add_argument("-v", "--version", action="version", version=__version__)
From 001f1420ea7691eca463d3b75990c5901ba3ea21 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:41:32 +0000
Subject: [PATCH 08/45] Update README.md
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 7894e37..6f58ac6 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,7 @@ To install and run nii2dcm locally, you have two options:
### pip
+Create a new Python virtual environment, then:
```shell
pip install nii2dcm
```
From dce9133ad727323910bc7a4bc4db1f79473032fd Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:41:50 +0000
Subject: [PATCH 09/45] Adds setuptools and wheel to requirements.txt
---
README.md | 1 -
requirements.txt | 2 ++
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 6f58ac6..68cc552 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,6 @@ python -m pip install --upgrade pip
Install dependencies and nii2dcm:
```sh
-pip install setuptools wheel
pip install -r requirements.txt
pip install .
```
diff --git a/requirements.txt b/requirements.txt
index 91edd24..d7e88bb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,5 @@
+setuptools
+wheel
numpy==1.23.2
matplotlib==3.6.2
nibabel==5.0.0
From 66edf6b4a9c2b34fcc6efe6bf1ffbfb5d1872e4a Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 11:44:23 +0000
Subject: [PATCH 10/45] Removes sdist from PyPI build
---
.github/workflows/publish_pypi.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml
index 6f37c80..c201874 100644
--- a/.github/workflows/publish_pypi.yml
+++ b/.github/workflows/publish_pypi.yml
@@ -70,7 +70,7 @@ jobs:
- name: Create dist/
run: |
- python setup.py sdist bdist_wheel
+ python setup.py bdist_wheel
twine check dist/*
- name: Publish package to PyPI
From b0b47aef9c18adef42ade0742d73a570997d7c52 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 12:42:29 +0000
Subject: [PATCH 11/45] WIP: create Dockerfile
TODO: update pip install nii2dcm with PyPI version
---
Dockerfile | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 Dockerfile
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..abada6f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,21 @@
+# Use the official Python image as the base image
+FROM python:3.9-slim
+
+# Install system dependencies
+RUN apt-get update && apt-get install -y \
+ bash \
+ && apt-get clean
+
+RUN pip install --upgrade pip && \
+ pip install setuptools wheel
+
+RUN pip install --index-url https://test.pypi.org/simple/ \
+ --extra-index-url https://pypi.org/simple/ nii2dcm==0.1.2-post.11
+
+#RUN pip install nii2dcm
+
+# Test nii2dcm install
+# To see output locally during build process: docker build -t nii2dcm --progress=plain .
+RUN nii2dcm -h
+
+ENTRYPOINT ["nii2dcm"]
\ No newline at end of file
From 15942d9672e1feeba348d927c4726ce796269ee8 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 13:54:34 +0000
Subject: [PATCH 12/45] Update build_and_test GHA with container creation and
testing
---
.github/workflows/build_and_test_cli.yml | 31 ++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index 9c29120..03cf602 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -6,8 +6,8 @@ on:
pull_request:
jobs:
- build-and-test:
- name: Build
+ venv-build-and-test:
+ name: venv build
runs-on: ${{ matrix.os }}
@@ -65,3 +65,30 @@ jobs:
ls ./output
# assert DICOM files exist
[ -f "./output/IM_0001.dcm" ] && echo "Output DICOM file exists" || exit 1
+
+ container-build-and-test:
+ name: container build
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ ubuntu-latest ]
+ python-version: [ '3.9' ]
+
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Build container
+ run: |
+ docker build -t nii2dcm --progress=plain --no-cache .
+ docker ps
+
+ - name: Test nii2dcm container
+ run: |
+ docker run nii2dcm -h
+ echo "nii2dcm version:"
+ docker run nii2dcm -v
\ No newline at end of file
From d9b05e3728f8312e65443656b21e830ae690d604 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 15:44:32 +0000
Subject: [PATCH 13/45] Create test_dcm.py
---
tests/test_dcm.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 tests/test_dcm.py
diff --git a/tests/test_dcm.py b/tests/test_dcm.py
new file mode 100644
index 0000000..20bf1c3
--- /dev/null
+++ b/tests/test_dcm.py
@@ -0,0 +1,82 @@
+import pytest
+import os
+import datetime
+
+from pydicom.dataset import FileMetaDataset, FileDataset
+
+from nii2dcm.dcm import Dicom
+from nii2dcm.modules.patient import Patient
+
+
+TRANSFER_SYNTAX_UID = '1.2.840.10008.1.2.1'
+DATE = datetime.datetime.now().strftime('%Y%m%d')
+PATIENT_ID = '12345678'
+PATIENT_SEX = ''
+IMAGE_TYPE = ['SECONDARY', 'DERIVED']
+CHARACTER_SET = 'ISO_IR 100'
+
+MIN_UID_LENGTH = 10 # arbitrary just to check UID has some characters
+MAX_UID_LENGTH = 64 # DICOM standard max length
+
+class TestDicom:
+ def setup_method(self):
+ self.dicom = Dicom()
+
+ def test_dicom(self):
+ """
+ Tests some metadata in basic Dicom object
+ """
+ assert self.dicom.file_meta.TransferSyntaxUID == TRANSFER_SYNTAX_UID
+ assert self.dicom.ds.ContentDate == DATE
+ assert self.dicom.ds.AcquisitionDate == DATE
+ assert self.dicom.ds.SeriesDate == DATE
+ assert self.dicom.ds.StudyDate == DATE
+
+ def test_add_module(self):
+ """
+ Tests add_module() method
+ """
+ self.dicom.add_module(Patient())
+ assert self.dicom.ds.PatientID == PATIENT_ID
+ assert self.dicom.ds.PatientSex == PATIENT_SEX
+
+ def test_add_base_modules(self):
+ """
+ Test metadata present following bulk method invocation via add_base_modules()
+ """
+ self.dicom.add_base_modules()
+ assert self.dicom.ds.SpecificCharacterSet == CHARACTER_SET
+ assert self.dicom.ds.ImageType[0] == 'SECONDARY'
+ assert self.dicom.ds.ImageType[1] == 'DERIVED'
+
+ def test_get_file_meta(self):
+ fm = self.dicom.get_file_meta()
+ assert isinstance(fm, FileMetaDataset)
+
+ def test_get_dataset(self):
+ ds = self.dicom.get_dataset()
+ assert isinstance(ds, FileDataset)
+
+ def test_save_as(self):
+ """
+ Test DICOM save (default save location: cwd)
+ """
+ self.dicom.ds.save_as(self.dicom.filename)
+ assert os.path.exists(self.dicom.filename)
+ os.remove(self.dicom.filename)
+ if os.path.exists(self.dicom.filename):
+ raise Exception("Failed to delete temporary DICOM during pytest process.")
+
+ def test_init_study_tags(self):
+ self.dicom.init_study_tags()
+ assert isinstance(self.dicom.ds.StudyInstanceUID, str)
+ assert self.dicom.ds.StudyInstanceUID.find(".")
+ assert MIN_UID_LENGTH < len(self.dicom.ds.StudyInstanceUID) <= MAX_UID_LENGTH
+
+ def test_init_series_tags(self):
+ self.dicom.init_study_tags()
+ assert isinstance(self.dicom.ds.SeriesInstanceUID, str)
+ assert self.dicom.ds.SeriesInstanceUID.find(".")
+ assert MIN_UID_LENGTH < len(self.dicom.ds.SeriesInstanceUID) <= MAX_UID_LENGTH
+
+ assert len(str(self.dicom.ds.SeriesNumber)) == 4
From 23cf1b01ab9748d4f7cc454612e48657e691328e Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 15:56:57 +0000
Subject: [PATCH 14/45] Create test_version.py
---
tests/test_version.py | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 tests/test_version.py
diff --git a/tests/test_version.py b/tests/test_version.py
new file mode 100644
index 0000000..caf55d2
--- /dev/null
+++ b/tests/test_version.py
@@ -0,0 +1,9 @@
+import pytest
+from packaging import version
+
+from nii2dcm._version import __version__
+
+
+class TestVersion:
+ def test_version(self):
+ assert isinstance(version.parse(__version__), version.Version)
From f99e4fd567b558c3883022da3309cce0ce34934d Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 16:15:44 +0000
Subject: [PATCH 15/45] Amends Exception output
---
tests/test_dcm.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_dcm.py b/tests/test_dcm.py
index 20bf1c3..046dd0f 100644
--- a/tests/test_dcm.py
+++ b/tests/test_dcm.py
@@ -65,7 +65,7 @@ def test_save_as(self):
assert os.path.exists(self.dicom.filename)
os.remove(self.dicom.filename)
if os.path.exists(self.dicom.filename):
- raise Exception("Failed to delete temporary DICOM during pytest process.")
+ raise Exception("Failed to delete temporary DICOM created during pytest process.")
def test_init_study_tags(self):
self.dicom.init_study_tags()
From e23e41ba0a73b7c457aed517455853476695eccf Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 16:43:21 +0000
Subject: [PATCH 16/45] Changes variable name to slice_index for clarity
---
nii2dcm/dcm_writer.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/nii2dcm/dcm_writer.py b/nii2dcm/dcm_writer.py
index 4689376..f1291a8 100644
--- a/nii2dcm/dcm_writer.py
+++ b/nii2dcm/dcm_writer.py
@@ -6,19 +6,19 @@
import pydicom as pyd
-def write_slice(dcm, img_data, instance_index, output_dir):
+def write_slice(dcm, img_data, slice_index, output_dir):
"""
write a single DICOM slice
dcm – nii2dcm DICOM object
img_data - [nX, nY, nSlice] image pixel data, such as from NIfTI file
- instance_index – instance index (important: counts from 0)
+ slice_index – slice index in nibabel img_data array (important: counts from 0, whereas DICOM instances count from 1)
output_dir – output DICOM file save location
"""
- output_filename = r'IM_%04d.dcm' % (instance_index + 1) # begin filename from 1, e.g. IM_0001.dcm
+ output_filename = r'IM_%04d.dcm' % (slice_index + 1) # begin filename from 1, e.g. IM_0001.dcm
- img_slice = img_data[:, :, instance_index]
+ img_slice = img_data[:, :, slice_index]
# Instance UID – unique to current slice
dcm.ds.SOPInstanceUID = pyd.uid.generate_uid(None)
From a8a6c3e883da9d4b61937bc6b6eb5eed93f0cc28 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 16:44:15 +0000
Subject: [PATCH 17/45] Create test_dcm_writer.py
---
tests/test_dcm_writer.py | 46 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 tests/test_dcm_writer.py
diff --git a/tests/test_dcm_writer.py b/tests/test_dcm_writer.py
new file mode 100644
index 0000000..2b460a0
--- /dev/null
+++ b/tests/test_dcm_writer.py
@@ -0,0 +1,46 @@
+import os
+
+import pytest
+import nibabel as nib
+
+from nii2dcm import dcm_writer
+from nii2dcm.dcm import Dicom
+from nii2dcm.nii import Nifti
+
+
+NII_FILE_PATH = "tests/data/DicomMRISVR/t2-svr-atlas-35wk.nii.gz"
+INSTANCE_INDEX = 10 # dcm instances count from 1
+SLICE_NUMBER = INSTANCE_INDEX-1 # nibabel slice array counts from 0
+OUTPUT_DIR = "tests/data"
+OUTPUT_DCM_FILENAME = r'IM_%04d.dcm' % (INSTANCE_INDEX)
+OUTPUT_DCM_PATH = os.path.join(os.getcwd(), OUTPUT_DIR, OUTPUT_DCM_FILENAME)
+
+class TestDicomWriter:
+ def setup_method(self):
+ self.dicom = Dicom()
+ self.nii = nib.load(NII_FILE_PATH)
+ self.img_data = self.nii.get_fdata().astype("uint16")
+ self.nii2dcm_parameters = Nifti.get_nii2dcm_parameters(self.nii)
+
+ def test_write_slice(self):
+ dcm_writer.write_slice(self.dicom, self.img_data, SLICE_NUMBER, OUTPUT_DIR)
+
+ assert os.path.exists(OUTPUT_DCM_PATH)
+ os.remove(OUTPUT_DCM_PATH)
+ if os.path.exists(OUTPUT_DCM_PATH):
+ raise Exception("Failed to delete temporary DICOM created during pytest process.")
+
+ def test_transfer_nii_hdr_series_tags(self):
+ dcm_writer.transfer_nii_hdr_series_tags(self.dicom, self.nii2dcm_parameters)
+ assert self.dicom.ds.Rows == self.nii.shape[0]
+ assert self.dicom.ds.Columns == self.nii.shape[1]
+
+ def test_transfer_nii_hdr_instance_tags(self):
+ dcm_writer.transfer_nii_hdr_instance_tags(self.dicom, self.nii2dcm_parameters, SLICE_NUMBER)
+ assert self.dicom.ds.InstanceNumber == INSTANCE_INDEX
+
+ def test_transfer_ref_dicom_series_tags(self):
+ """
+ TODO: implement test
+ """
+ pass
From 32aec6d3ce1ee4302898b95cfada778187b042a9 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 17:15:55 +0000
Subject: [PATCH 18/45] Create test_nii.py
---
tests/test_nii.py | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 tests/test_nii.py
diff --git a/tests/test_nii.py b/tests/test_nii.py
new file mode 100644
index 0000000..d59e4a0
--- /dev/null
+++ b/tests/test_nii.py
@@ -0,0 +1,23 @@
+import pytest
+
+from nii2dcm.nii import Nifti
+import nibabel as nib
+
+
+NII_FILE_PATH = "tests/data/DicomMRISVR/t2-svr-atlas-35wk.nii.gz"
+NII_VOXEL_DIMS = (180, 221, 180)
+NII_VOXEL_SPACING = (0.5, 0.5, 0.5)
+
+class TestNifti:
+ def setup_method(self):
+ self.nii = nib.load(NII_FILE_PATH)
+
+ def test_get_nii2dcm_parameters(self):
+ nii_parameters = Nifti.get_nii2dcm_parameters(self.nii)
+ assert nii_parameters["Rows"] == NII_VOXEL_DIMS[0]
+ assert nii_parameters["Columns"] == NII_VOXEL_DIMS[1]
+ assert nii_parameters["NumberOfSlices"] == NII_VOXEL_DIMS[2]
+ assert nii_parameters["AcquisitionMatrix"] == [0, NII_VOXEL_DIMS[0], NII_VOXEL_DIMS[1], 0]
+ assert nii_parameters["dimX"] == NII_VOXEL_SPACING[0]
+ assert nii_parameters["dimY"] == NII_VOXEL_SPACING[1]
+ assert nii_parameters["SliceThickness"] == str(NII_VOXEL_SPACING[2])
From 7003bf117f55ef3c633ae0f54e845cff7ce6dfd2 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Tue, 20 Feb 2024 17:54:16 +0000
Subject: [PATCH 19/45] Create test_run.py
---
tests/test_run.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 tests/test_run.py
diff --git a/tests/test_run.py b/tests/test_run.py
new file mode 100644
index 0000000..8c95343
--- /dev/null
+++ b/tests/test_run.py
@@ -0,0 +1,55 @@
+import pytest
+import os, shutil
+import pydicom as pyd
+
+from nii2dcm.run import run_nii2dcm
+
+
+NII_FILE_PATH = "tests/data/DicomMRISVR/t2-svr-atlas-35wk.nii.gz"
+OUTPUT_DIR = "tests/data/tmp_dcm_dir"
+OUTPUT_DCM_PATH = os.path.join(os.getcwd(), OUTPUT_DIR)
+NUM_DICOM_FILES = 180
+SINGLE_DICOM_FILENAME = "IM_0001.dcm"
+
+class TestRun:
+ def setup_method(self):
+ os.makedirs(OUTPUT_DCM_PATH, exist_ok=True)
+
+ @pytest.mark.parametrize(
+ "TEST_DICOM_TYPE, TEST_DCM_MODALITY",
+ [
+ (None, ''), # basic DICOM with undefined modality
+ ("MR", "MR"), # MRI DICOM
+ ("SVR", "MR") # SVR DICOM hence MR modality
+ ]
+ )
+ def test_run_dicom_types(self, TEST_DICOM_TYPE, TEST_DCM_MODALITY):
+ """
+ Test run_nii2dcm with different dicom_types
+ """
+ run_nii2dcm(
+ NII_FILE_PATH,
+ OUTPUT_DCM_PATH,
+ dicom_type=TEST_DICOM_TYPE
+ )
+ assert os.path.exists(os.path.join(OUTPUT_DCM_PATH, SINGLE_DICOM_FILENAME))
+ assert len(os.listdir(OUTPUT_DCM_PATH)) == NUM_DICOM_FILES
+
+ ds = pyd.dcmread(os.path.join(OUTPUT_DCM_PATH, SINGLE_DICOM_FILENAME))
+ assert ds.Modality == TEST_DCM_MODALITY
+
+ shutil.rmtree(OUTPUT_DCM_PATH)
+
+ def test_run_reference_dicom(self):
+ """
+ Test run_nii2dcm with different ref_dicom option
+ """
+ # TODO: implement - will involve adding reference DICOM test dataset
+ pass
+
+ def teardown_method(self):
+ """
+ Remove output DICOM directory in event of test failure
+ """
+ if os.path.exists(OUTPUT_DCM_PATH):
+ shutil.rmtree(OUTPUT_DCM_PATH)
From b2bec4260a7edca0900ccc34beb9928a857fad8f Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 16:54:40 +0000
Subject: [PATCH 20/45] Adds unit tests to GHA
---
.github/workflows/build_and_test_cli.yml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index 9c29120..0e49478 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -1,4 +1,4 @@
-# Workflow to build nii2dcm and test different command line interface (CLI) options
+# Workflow to build nii2dcm, run unit tests and then execute command line interface (CLI) end-to-end
name: Build nii2dcm
@@ -7,7 +7,7 @@ on:
jobs:
build-and-test:
- name: Build
+ name: Build, Unit Tests & E2E
runs-on: ${{ matrix.os }}
@@ -57,6 +57,10 @@ jobs:
nii2dcm -h
nii2dcm -v
+ - name: Run unit tests
+ run: |
+ pytest tests/
+
- name: Test DicomMRISVR creation
run: |
# run nii2dcm
From ccb57eb85a343a9608629a9f750956dd8edb2e15 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 17:22:18 +0000
Subject: [PATCH 21/45] Adds pytest coverage comment/badge to GHA
---
.github/workflows/build_and_test_cli.yml | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index 0e49478..4f218f1 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -69,3 +69,24 @@ jobs:
ls ./output
# assert DICOM files exist
[ -f "./output/IM_0001.dcm" ] && echo "Output DICOM file exists" || exit 1
+
+ - name: Build pytest coverage file
+ run: |
+ pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=nii2dcm tests/ | tee pytest-coverage.txt ; echo $?
+
+ - name: Pytest coverage comment
+ uses: MishaKav/pytest-coverage-comment@main
+ with:
+ pytest-coverage-path: ./pytest-coverage.txt
+ junitxml-path: ./pytest.xml
+
+ - name: Update Coverage Badge
+ uses: schneegans/dynamic-badges-action@v1.7.0
+ with:
+ auth: ${{ secrets.PYTEST_COVERAGE_COMMENT }}
+ gistID: 57ef8057d04f67dbe6e64df410b83079
+ filename: nii2dcm-pytest-coverage-comment.json
+ label: Coverage Report
+ message: ${{ steps.coverageComment.outputs.coverage }}
+ color: ${{ steps.coverageComment.outputs.color }}
+ namedLogo: python
From 54e783b99c161609e8a34f55fb3b6bcbce3f1429 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 17:35:53 +0000
Subject: [PATCH 22/45] Updates README with coverage badges
---
README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/README.md b/README.md
index 68cc552..f277715 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,10 @@
·
Request Feature
+
+
+
+
From 765af048a71f4627224e269ab3cc7d6278d96801 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 17:57:50 +0000
Subject: [PATCH 23/45] Fixes some formatting issues
---
nii2dcm/__main__.py | 2 +-
nii2dcm/_version.py | 2 +-
nii2dcm/dcm.py | 3 +--
nii2dcm/modules/mr_image.py | 4 ++--
4 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/nii2dcm/__main__.py b/nii2dcm/__main__.py
index abd393e..f3ff34c 100644
--- a/nii2dcm/__main__.py
+++ b/nii2dcm/__main__.py
@@ -24,7 +24,7 @@ def cli(args=None):
parser.add_argument("input_file", type=str, help="[.nii/.nii.gz] input NIfTI file")
parser.add_argument("output_dir", type=str, help="[directory] output DICOM path")
parser.add_argument(
- "-d","--dicom_type",
+ "-d", "--dicom_type",
type=str,
help="[string] type of DICOM. Available types: MR, SVR."
)
diff --git a/nii2dcm/_version.py b/nii2dcm/_version.py
index 0699dbf..2a05741 100644
--- a/nii2dcm/_version.py
+++ b/nii2dcm/_version.py
@@ -1,2 +1,2 @@
import dunamai as _dunamai
-__version__ = _dunamai.get_version("nii2dcm", third_choice=_dunamai.Version.from_any_vcs).serialize()
\ No newline at end of file
+__version__ = _dunamai.get_version("nii2dcm", third_choice=_dunamai.Version.from_any_vcs).serialize()
diff --git a/nii2dcm/dcm.py b/nii2dcm/dcm.py
index 7421db0..a7c537a 100644
--- a/nii2dcm/dcm.py
+++ b/nii2dcm/dcm.py
@@ -11,7 +11,6 @@
import pydicom as pyd
from pydicom.dataset import FileDataset, FileMetaDataset
-from nii2dcm.utils import dcm_dictionary_update
from nii2dcm.modules.patient import Patient
from nii2dcm.modules.general_study import GeneralStudy
from nii2dcm.modules.patient_study import PatientStudy
@@ -67,7 +66,7 @@ def __init__(self, filename=nii2dcm_temp_filename):
"""
Set Dicom Date/Time
- Important: doing this once sets all Instances/Series/Study creation dates and times to the same values. Whereas,
+ Important: doing this once sets all Instances/Series/Study creation dates and times to the same values. Whereas,
doing this within the Modules would every so slightly offset the times
"""
# TODO shift to utils.py and propagate to Modules, or, create method within this Dicom class
diff --git a/nii2dcm/modules/mr_image.py b/nii2dcm/modules/mr_image.py
index 7f146da..a460ca7 100644
--- a/nii2dcm/modules/mr_image.py
+++ b/nii2dcm/modules/mr_image.py
@@ -24,9 +24,9 @@ def __init__(self):
# https://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.8.3.html#sect_C.8.3.1.1.1
# For now, will omit thereby inheriting parent value
# self.ds.ImageType = ''
-
+
self.ds.SamplesPerPixel = 1
-
+
# PhotometricInterpretation
# TODO: decide MONOCHROME1 or MONOCHROME2 as default
# https://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2
From e4cf41d97c9151bbdf70e93aae4b1cd6619a783f Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 18:17:25 +0000
Subject: [PATCH 24/45] Amends and re-tests pytest coverage badge
---
.github/workflows/build_and_test_cli.yml | 3 ++-
README.md | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index 4f218f1..b3a81e1 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -75,7 +75,8 @@ jobs:
pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=nii2dcm tests/ | tee pytest-coverage.txt ; echo $?
- name: Pytest coverage comment
- uses: MishaKav/pytest-coverage-comment@main
+ id: coverageComment
+ uses: MishaKav/pytest-coverage-comment@unit-tests
with:
pytest-coverage-path: ./pytest-coverage.txt
junitxml-path: ./pytest.xml
diff --git a/README.md b/README.md
index f277715..0a30d62 100644
--- a/README.md
+++ b/README.md
@@ -22,8 +22,8 @@
-
-
+
+
From 2deaf280900b25f3a0bf2601f73f0a82b6930cf2 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 18:18:59 +0000
Subject: [PATCH 25/45] =?UTF-8?q?Typo=20=E2=80=93=20re-test?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/build_and_test_cli.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index b3a81e1..1497aef 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -76,7 +76,7 @@ jobs:
- name: Pytest coverage comment
id: coverageComment
- uses: MishaKav/pytest-coverage-comment@unit-tests
+ uses: MishaKav/pytest-coverage-comment@main
with:
pytest-coverage-path: ./pytest-coverage.txt
junitxml-path: ./pytest.xml
From 0f382d9bf3f178bb8749d4849a3fd2b14330b583 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 18:21:19 +0000
Subject: [PATCH 26/45] Test coverage badge on unit-tests branch
---
.github/workflows/build_and_test_cli.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index 1497aef..f3a662c 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -80,6 +80,7 @@ jobs:
with:
pytest-coverage-path: ./pytest-coverage.txt
junitxml-path: ./pytest.xml
+ default-branch: unit-tests
- name: Update Coverage Badge
uses: schneegans/dynamic-badges-action@v1.7.0
From be589f94ca63ba0fec0ba1ac613180a79857657e Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 18:32:57 +0000
Subject: [PATCH 27/45] Create __init__.py
---
tests/__init__.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 tests/__init__.py
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
From 2bb4058c37d1bebb3444dcecc15daf1d4ef89631 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Wed, 21 Feb 2024 18:35:18 +0000
Subject: [PATCH 28/45] Update .gitignore
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
index d7c3b9c..8234174 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,8 @@ coverage.xml
.hypothesis/
.pytest_cache/
cover/
+pytest-coverage.txt
+pytest.xml
# Sphinx documentation
docs/_build/
From 1f972949b23f55c03c94e68450f3d3577b997214 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Thu, 22 Feb 2024 17:21:36 +0000
Subject: [PATCH 29/45] Adds Docker section to README
---
README.md | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/README.md b/README.md
index 0a30d62..3e6cade 100644
--- a/README.md
+++ b/README.md
@@ -142,6 +142,26 @@ Currently, attributes to transfer are [listed here in the DicomMRI class](https:
(back to top)
+
+## Docker
+nii2dcm is also available as a Docker container.
+
+Pull the latest container with:
+```shell
+docker pull ghcr.io/tomaroberts/nii2dcm/nii2dcm:latest
+```
+
+Run the containerised nii2dcm:
+```shell
+# display nii2dcm version
+docker run nii2dcm -v
+
+# perform nii2dcm conversion
+docker run nii2dcm nifti-file.nii.gz dicom-output-directory/ -d MR
+```
+
+(back to top)
+
## Roadmap
From 4edd9eb571d5cda0dc71385250a0d3a33b2f4242 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 10:30:36 +0000
Subject: [PATCH 30/45] Test container build GHA
---
.github/workflows/publish_testpypi.yml | 32 ++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index e8b22f6..9c57ec7 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -96,3 +96,35 @@ jobs:
nii2dcm -h
echo "nii2dcm version:"
nii2dcm -v
+
+ ghcr-publish:
+ needs: testpypi-publish
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Log in to the Container registry
+ uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GHCR_TOKEN }}
+
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
+ with:
+ context: .
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
From a711e2e20f75d7460b96e148c6480bc46da2cc66 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 12:42:53 +0000
Subject: [PATCH 31/45] Adds LABEL
---
Dockerfile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Dockerfile b/Dockerfile
index abada6f..1ba41d2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,8 @@
# Use the official Python image as the base image
FROM python:3.9-slim
+LABEL org.opencontainers.image.source https://github.com/tomaroberts/nii2dcm
+
# Install system dependencies
RUN apt-get update && apt-get install -y \
bash \
From e538735959b766cdfacbe3097bcdb6daca028a17 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 12:43:01 +0000
Subject: [PATCH 32/45] Revert "Test container build GHA"
This reverts commit 4edd9eb571d5cda0dc71385250a0d3a33b2f4242.
---
.github/workflows/publish_testpypi.yml | 32 --------------------------
1 file changed, 32 deletions(-)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index 9c57ec7..e8b22f6 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -96,35 +96,3 @@ jobs:
nii2dcm -h
echo "nii2dcm version:"
nii2dcm -v
-
- ghcr-publish:
- needs: testpypi-publish
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
- packages: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
- - name: Log in to the Container registry
- uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
- with:
- registry: ${{ env.REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GHCR_TOKEN }}
-
- - name: Extract metadata (tags, labels) for Docker
- id: meta
- uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
- with:
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
-
- - name: Build and push Docker image
- uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
- with:
- context: .
- push: true
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
From 5539c404d5dd7e9edad2013e3456379005d442d1 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 12:43:43 +0000
Subject: [PATCH 33/45] Adds publish container to GHCR workflow
---
.github/workflows/publish_ghcr.yml | 51 ++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 .github/workflows/publish_ghcr.yml
diff --git a/.github/workflows/publish_ghcr.yml b/.github/workflows/publish_ghcr.yml
new file mode 100644
index 0000000..1a282bc
--- /dev/null
+++ b/.github/workflows/publish_ghcr.yml
@@ -0,0 +1,51 @@
+# Publish container to GHCR
+#
+# This workflow builds a nii2dcm container and publishes to GHCR
+
+name: Create and publish container on GHCR
+on:
+ release:
+ types: [published]
+ push:
+ branches:
+ - docker-build
+ workflow_run:
+ workflows: ["Publish package to TestPyPI"]
+ types:
+ - completed
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ build-and-push-image:
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Log in to the Container registry
+ uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GHCR_TOKEN }}
+
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
+ with:
+ context: .
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
\ No newline at end of file
From bd824eb738a4af54cb9fa6afa4e8145c81ba5af2 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 12:47:30 +0000
Subject: [PATCH 34/45] Update publish_ghcr.yml
---
.github/workflows/publish_ghcr.yml | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/.github/workflows/publish_ghcr.yml b/.github/workflows/publish_ghcr.yml
index 1a282bc..51912b0 100644
--- a/.github/workflows/publish_ghcr.yml
+++ b/.github/workflows/publish_ghcr.yml
@@ -4,11 +4,6 @@
name: Create and publish container on GHCR
on:
- release:
- types: [published]
- push:
- branches:
- - docker-build
workflow_run:
workflows: ["Publish package to TestPyPI"]
types:
@@ -34,7 +29,7 @@ jobs:
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
- password: ${{ secrets.GHCR_TOKEN }}
+ password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
From d2e69035c1d2fd1c484bba71a01b4ea1b42c322f Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 12:52:38 +0000
Subject: [PATCH 35/45] Update publish_ghcr.yml
---
.github/workflows/publish_ghcr.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/publish_ghcr.yml b/.github/workflows/publish_ghcr.yml
index 51912b0..8aec2ff 100644
--- a/.github/workflows/publish_ghcr.yml
+++ b/.github/workflows/publish_ghcr.yml
@@ -1,6 +1,7 @@
# Publish container to GHCR
#
# This workflow builds a nii2dcm container and publishes to GHCR
+#
name: Create and publish container on GHCR
on:
From 0fcb428fa57e4e158203321daea75a37a0697ac8 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 13:16:26 +0000
Subject: [PATCH 36/45] Test container build with TestPyPI package build
---
.github/workflows/build_and_test_cli.yml | 4 +-
.github/workflows/publish_ghcr.yml | 47 ------------------------
.github/workflows/publish_testpypi.yml | 32 ++++++++++++++++
3 files changed, 34 insertions(+), 49 deletions(-)
delete mode 100644 .github/workflows/publish_ghcr.yml
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index 120e24d..5cfa47e 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -6,8 +6,8 @@ on:
pull_request:
jobs:
- build-and-test:
- name: Build, Unit Tests & E2E
+ venv-build-and-test:
+ name: venv Build, Unit Tests & E2E
runs-on: ${{ matrix.os }}
diff --git a/.github/workflows/publish_ghcr.yml b/.github/workflows/publish_ghcr.yml
deleted file mode 100644
index 8aec2ff..0000000
--- a/.github/workflows/publish_ghcr.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-# Publish container to GHCR
-#
-# This workflow builds a nii2dcm container and publishes to GHCR
-#
-
-name: Create and publish container on GHCR
-on:
- workflow_run:
- workflows: ["Publish package to TestPyPI"]
- types:
- - completed
-
-env:
- REGISTRY: ghcr.io
- IMAGE_NAME: ${{ github.repository }}
-
-jobs:
- build-and-push-image:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
- packages: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
- - name: Log in to the Container registry
- uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
- with:
- registry: ${{ env.REGISTRY }}
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Extract metadata (tags, labels) for Docker
- id: meta
- uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
- with:
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
-
- - name: Build and push Docker image
- uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
- with:
- context: .
- push: true
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
\ No newline at end of file
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index e8b22f6..9c57ec7 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -96,3 +96,35 @@ jobs:
nii2dcm -h
echo "nii2dcm version:"
nii2dcm -v
+
+ ghcr-publish:
+ needs: testpypi-publish
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Log in to the Container registry
+ uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GHCR_TOKEN }}
+
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
+ with:
+ context: .
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
From c3d6e996b9f121bcac10e581aa9614b81764c5f6 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 13:30:16 +0000
Subject: [PATCH 37/45] Update publish_testpypi.yml
---
.github/workflows/publish_testpypi.yml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index 9c57ec7..630f0bf 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -108,10 +108,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
+
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
- registry: ${{ env.REGISTRY }}
+ registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHCR_TOKEN }}
@@ -119,7 +120,9 @@ jobs:
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ images: |
+ ghcr.io/tomaroberts/nii2dcm
+
- name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
From 975800a3e728c4372528482d9a9d07503849101b Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 13:38:34 +0000
Subject: [PATCH 38/45] Re-test
---
.github/workflows/publish_testpypi.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index 630f0bf..fb495e0 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -12,6 +12,7 @@
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
+#
name: Publish package to TestPyPI
@@ -108,7 +109,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
-
+
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
From 94e6c8171393bdc3ea0896fb0f3f8518168694bb Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 13:52:14 +0000
Subject: [PATCH 39/45] Adds second wait time if TestPyPI install fails
---
.github/workflows/publish_testpypi.yml | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index fb495e0..9773ab0 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -86,6 +86,28 @@ jobs:
time: '150' # seconds
- name: Install latest TestPyPI version in fresh venv
+ id: attempt1
+ run: |
+ NII2DCM_VERSION=`echo "$(nii2dcm -v)"`
+ echo $NII2DCM_VERSION
+ python -m venv nii2dcm-temp
+ source nii2dcm-temp/bin/activate
+ pip install --upgrade pip
+ pip install setuptools wheel
+ pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ nii2dcm==$NII2DCM_VERSION
+ nii2dcm -h
+ echo "nii2dcm version:"
+ nii2dcm -v
+ continue-on-error: true
+
+ - name: Wait longer
+ if: steps.attempt1.outcome != 'success'
+ uses: GuillaumeFalourd/wait-sleep-action@v1
+ with:
+ time: '150' # seconds
+
+ - name: Re-attempt TestPyPI install
+ if: steps.attempt1.outcome != 'success'
run: |
NII2DCM_VERSION=`echo "$(nii2dcm -v)"`
echo $NII2DCM_VERSION
From 2b72406d06fa1eeca3bc65092d97caab03c1910d Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 14:06:07 +0000
Subject: [PATCH 40/45] Test updated secrets
---
.github/workflows/publish_testpypi.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index 9773ab0..e1293d4 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -132,23 +132,23 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- - name: Log in to the Container registry
- uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+ - name: Log in to GHCR
+ uses: docker/login-action@v3
with:
registry: ghcr.io
- username: ${{ github.actor }}
+ username: ${{ secrets.GHCR_USERNAME }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
- uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
+ uses: docker/metadata-action@v5
with:
images: |
ghcr.io/tomaroberts/nii2dcm
- name: Build and push Docker image
- uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
+ uses: docker/build-push-action@v5
with:
context: .
push: true
From e9a0c42718f1ef943283f72297327916ad52faa3 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 15:20:50 +0000
Subject: [PATCH 41/45] Moves container GHCR build to PyPI release GHA
---
.github/workflows/publish_pypi.yml | 59 +++++++++++++++++++++++++-
.github/workflows/publish_testpypi.yml | 35 ---------------
2 files changed, 58 insertions(+), 36 deletions(-)
diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml
index c201874..fbf32fb 100644
--- a/.github/workflows/publish_pypi.yml
+++ b/.github/workflows/publish_pypi.yml
@@ -27,7 +27,7 @@ permissions:
actions: write
jobs:
- testpypi-publish:
+ pypi-publish:
name: Publish to PyPI
runs-on: ubuntu-latest
@@ -86,6 +86,7 @@ jobs:
time: '150' # seconds
- name: Install latest PyPI version in fresh venv
+ id: attempt1
run: |
NII2DCM_VERSION=`echo "$(nii2dcm -v)"`
echo $NII2DCM_VERSION
@@ -97,3 +98,59 @@ jobs:
nii2dcm -h
echo "nii2dcm version:"
nii2dcm -v
+ continue-on-error: true
+
+ - name: Wait longer
+ if: steps.attempt1.outcome != 'success'
+ uses: GuillaumeFalourd/wait-sleep-action@v1
+ with:
+ time: '150' # seconds
+
+ - name: Re-attempt PyPI install
+ if: steps.attempt1.outcome != 'success'
+ run: |
+ NII2DCM_VERSION=`echo "$(nii2dcm -v)"`
+ echo $NII2DCM_VERSION
+ python -m venv nii2dcm-temp
+ source nii2dcm-temp/bin/activate
+ pip install --upgrade pip
+ pip install setuptools wheel
+ pip install nii2dcm==$NII2DCM_VERSION
+ nii2dcm -h
+ echo "nii2dcm version:"
+ nii2dcm -v
+
+ ghcr-publish:
+ needs: pypi-publish
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Log in to GHCR
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ secrets.GHCR_USERNAME }}
+ password: ${{ secrets.GHCR_TOKEN }}
+
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: |
+ ghcr.io/tomaroberts/nii2dcm
+
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
diff --git a/.github/workflows/publish_testpypi.yml b/.github/workflows/publish_testpypi.yml
index e1293d4..9a250d7 100644
--- a/.github/workflows/publish_testpypi.yml
+++ b/.github/workflows/publish_testpypi.yml
@@ -119,38 +119,3 @@ jobs:
nii2dcm -h
echo "nii2dcm version:"
nii2dcm -v
-
- ghcr-publish:
- needs: testpypi-publish
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
- packages: write
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Log in to GHCR
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ secrets.GHCR_USERNAME }}
- password: ${{ secrets.GHCR_TOKEN }}
-
- - name: Extract metadata (tags, labels) for Docker
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: |
- ghcr.io/tomaroberts/nii2dcm
-
-
- - name: Build and push Docker image
- uses: docker/build-push-action@v5
- with:
- context: .
- push: true
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
From c8473c7f761b00ccc7fbcc44c807f82fa1bf81b3 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 15:21:01 +0000
Subject: [PATCH 42/45] Minor formatting changes
---
.github/workflows/build_and_test_cli.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index 5cfa47e..04ac3fb 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -1,13 +1,13 @@
# Workflow to build nii2dcm, run unit tests and then execute command line interface (CLI) end-to-end
-name: Build nii2dcm
+name: Build & Test nii2dcm
on:
pull_request:
jobs:
venv-build-and-test:
- name: venv Build, Unit Tests & E2E
+ name: venv + E2E
runs-on: ${{ matrix.os }}
@@ -94,7 +94,7 @@ jobs:
namedLogo: python
container-build-and-test:
- name: Container Build & Test
+ name: Container
runs-on: ${{ matrix.os }}
From d46fbf44dbf2c29eb50dae03c42d67634ec8d1b9 Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 15:38:55 +0000
Subject: [PATCH 43/45] Formatting fix
---
.github/workflows/publish_pypi.yml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml
index fbf32fb..5ca0459 100644
--- a/.github/workflows/publish_pypi.yml
+++ b/.github/workflows/publish_pypi.yml
@@ -146,7 +146,6 @@ jobs:
images: |
ghcr.io/tomaroberts/nii2dcm
-
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
From ee2cc62036148494632a6bc2270a569eed50fa3e Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 15:45:53 +0000
Subject: [PATCH 44/45] Update so coverage comment displayed on all branches
---
.github/workflows/build_and_test_cli.yml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/workflows/build_and_test_cli.yml b/.github/workflows/build_and_test_cli.yml
index f3a662c..1497aef 100644
--- a/.github/workflows/build_and_test_cli.yml
+++ b/.github/workflows/build_and_test_cli.yml
@@ -80,7 +80,6 @@ jobs:
with:
pytest-coverage-path: ./pytest-coverage.txt
junitxml-path: ./pytest.xml
- default-branch: unit-tests
- name: Update Coverage Badge
uses: schneegans/dynamic-badges-action@v1.7.0
From ee02e23839ec322fe5aa9b543e32bab70a9557ec Mon Sep 17 00:00:00 2001
From: Tom Roberts
Date: Fri, 1 Mar 2024 16:17:11 +0000
Subject: [PATCH 45/45] Update Dockerfile to build from source
---
Dockerfile | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 1ba41d2..7bd4b02 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,18 +3,24 @@ FROM python:3.9-slim
LABEL org.opencontainers.image.source https://github.com/tomaroberts/nii2dcm
+# Setup
+COPY . /home/nii2dcm
+WORKDIR /home/nii2dcm
+
# Install system dependencies
RUN apt-get update && apt-get install -y \
- bash \
+ bash git \
&& apt-get clean
+# Update base packages
RUN pip install --upgrade pip && \
pip install setuptools wheel
-RUN pip install --index-url https://test.pypi.org/simple/ \
- --extra-index-url https://pypi.org/simple/ nii2dcm==0.1.2-post.11
+# Install nii2dcm requirements
+RUN pip install -r requirements.txt
-#RUN pip install nii2dcm
+# Build package from source
+RUN pip install .
# Test nii2dcm install
# To see output locally during build process: docker build -t nii2dcm --progress=plain .