Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Revisions to skip in `git blame`.
#
# Enable locally with:
# git config blame.ignoreRevsFile .git-blame-ignore-revs
#
# GitHub picks this file up automatically.

# style: apply ruff autofix and formatter (#34)
4c78918e1be261ca2373f1fbfb302654c7803a03
12 changes: 12 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Owners are requested for review automatically on every pull request.
# Combined with a branch protection rule requiring one approval, this is the
# "requiring code-review" half of issue #34.
#
# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

* @Hendrik-code @NathanMolinier

# Changing the CI, packaging or linting setup affects every contributor.
/.github/ @Hendrik-code
/pyproject.toml @Hendrik-code
/.pre-commit-config.yaml @Hendrik-code
45 changes: 45 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
name: Bug report
about: Something does not work as expected
title: ''
labels: bug
assignees: ''
---

**Describe the bug**
A clear and concise description of what goes wrong.

**To reproduce**
Steps to reproduce the behaviour, ideally with the exact command:

```bash
# e.g. AUGLAB_PARAMS_GPU_JSON=/abs/path/params.json nnUNetv2_train 100 3d_fullres 0 -tr nnUNetTrainerDAExtGPU
```

**Config JSON**
If the problem involves augmentation parameters, paste the relevant part of your
transform params JSON (or attach the file).

```json

```

**Expected behaviour**
What you expected to happen instead.

**Error output**
The full traceback, not just the last line.

```

```

**Environment**
- AugLab version or commit:
- Python version:
- PyTorch version and CUDA build:
- nnU-Net version (if applicable):
- OS:

**Additional context**
Anything else that might matter — dataset, image orientation, patch size.
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: Feature request
about: Suggest a new augmentation, option, or improvement
title: ''
labels: enhancement
assignees: ''
---

**What problem does this solve?**
A clear description of the limitation you are hitting.

**Proposed solution**
What you would like AugLab to do.

**If this is a new augmentation**
- What does it simulate (acquisition artefact, contrast change, anatomy change)?
- Reference or paper, if there is one:
- Should it run on GPU, CPU, or both?
- What parameters should the config JSON expose?

**Alternatives considered**
Other approaches you thought about.

**Additional context**
Screenshots, example images, or links.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Question
about: Ask about usage, configuration, or results
title: ''
labels: question
assignees: ''
---

**Your question**
What you are trying to do and where you are stuck.

**What you have tried**
Commands, config JSONs, or documentation you already looked at.

**Environment (if relevant)**
- AugLab version or commit:
- Python / PyTorch version:
26 changes: 26 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## What does this change?

<!-- A short description. If it fixes an issue, write "Fixes #123" so GitHub links them. -->

## Why?

<!-- The motivation. What was broken or missing? -->

## How was it tested?

<!-- Delete what does not apply. -->

- [ ] `pytest` passes locally
- [ ] `pre-commit run --all-files` passes
- [ ] Added or updated tests covering the change
- [ ] Ran a training / augmentation job end to end

## Anything reviewers should look at closely?

<!-- Tricky bits, trade-offs, or decisions you were unsure about. -->

## Checklist

- [ ] Augmentation behaviour is unchanged, or the change is intentional and described above
- [ ] New transforms are reachable from a config JSON
- [ ] `project.version` in `pyproject.toml` bumped, if this should be released
33 changes: 33 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: lint

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

concurrency:
group: lint-${{ github.ref }}
cancel-in-progress: true

jobs:
# Runs the pre-commit hooks rather than a bare `ruff check`, so the hooks
# contributors run locally and the ones CI enforces cannot drift apart.
#
# Deliberately does NOT auto-commit fixes back to the branch: that breaks on
# pull requests from forks and rewrites contributors' branches under them.
# A red check plus `pre-commit run --all-files` locally is the fix.
pre-commit:
name: pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- uses: pre-commit/action@v3.0.1
125 changes: 125 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: publish to PyPI

on:
release:
types: [created]
workflow_dispatch:
inputs:
repository:
description: Which index to upload to
required: true
default: testpypi
type: choice
options: [testpypi, pypi]

permissions:
contents: read

jobs:
publish:
name: build and upload
runs-on: ubuntu-latest
# Requires the PYPI_API_TOKEN (and, for dry runs, TEST_PYPI_API_TOKEN)
# repository secret. Until that is set by an admin this job cannot upload.
environment: pypi

steps:
- uses: actions/checkout@v4
with:
# poetry-dynamic-versioning derives the version from the git tag;
# a shallow clone has no tags and would build as 0.0.0.
fetch-depth: 0

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install build tooling
run: |
python -m pip install --upgrade pip
pip install build twine

- name: Build sdist and wheel
run: python -m build

- name: Check the built version came from the release tag
# poetry-dynamic-versioning derives the version from the tag, so the two cannot
# disagree the way a hand-maintained project.version could. What can
# still go wrong is the tag not matching [tool.poetry-dynamic-versioning].pattern,
# or the checkout arriving without tags -- both of which silently yield
# the 0.0.0 fallback or a .dev version. Catch that before uploading.
if: github.event_name == 'release'
run: |
python - <<'PY'
import glob, os, pathlib, re, sys

from packaging.version import InvalidVersion, Version

tag = os.environ["RELEASE_TAG"]
# Same prefixes as [tool.poetry-dynamic-versioning].pattern.
expected = re.sub(r"^(?:[rvV]|release[-_])", "", tag)
built = {pathlib.Path(p).name.split("-")[1] for p in glob.glob("dist/*.whl")}

print(f"tag={tag!r} expected={expected!r} built={sorted(built)}")

# Compare parsed versions, not strings: a tag like v2.0.0-beta1 is
# legitimately normalised to 2.0.0b1 in the artifact name.
try:
if {Version(b) for b in built} != {Version(expected)}:
raise InvalidVersion
except InvalidVersion:
sys.exit(
f"built version {sorted(built)} does not match release tag '{tag}'. "
"Either the tag does not match [tool.poetry-dynamic-versioning].pattern in "
"pyproject.toml, or the checkout has no tags (needs fetch-depth: 0)."
)
PY
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}

- name: Refuse to publish a fallback version
run: |
python - <<'PY'
import glob, pathlib, sys

built = {pathlib.Path(p).name.split("-")[1] for p in glob.glob("dist/*.whl")}
if "0.0.0" in built:
sys.exit(
"refusing to publish 0.0.0 -- poetry-dynamic-versioning found no git tag, so the "
"version is the fallback rather than a real release"
)
print(f"version looks real: {sorted(built)}")
PY

- name: Check distribution metadata
run: twine check dist/*

- name: Verify the wheel ships the package data
run: |
python - <<'PY'
import glob, sys, zipfile

names = zipfile.ZipFile(glob.glob("dist/*.whl")[0]).namelist()
if "auglab/configs/transform_params_gpu.json" not in names:
sys.exit("refusing to publish: wheel has no config JSONs")
if len([n for n in names if n.endswith(".py")]) < 20:
sys.exit("refusing to publish: wheel is missing modules")
print("wheel contents look complete")
PY

- name: Upload to TestPyPI
if: github.event_name == 'workflow_dispatch' && inputs.repository == 'testpypi'
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
TWINE_REPOSITORY: testpypi
run: twine upload dist/*

- name: Upload to PyPI
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.repository == 'pypi')
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
# Uploads the sdist as well as the wheel; auglab currently has no sdist
# on PyPI, which blocks anyone who needs to build from source.
run: twine upload dist/*
Loading
Loading