Skip to content
Merged
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
6 changes: 4 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ jobs:
auto-update-conda: true
auto-activate-base: true
activate-environment: ""
channel-priority: strict
miniforge-variant: Miniforge3
- name: linux conda build and upload
shell: bash -l {0}
env:
ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }}
run: |
conda install -n base -c conda-forge conda-build mamba boa anaconda-client -y
conda install -n base -c conda-forge conda-build anaconda-client -y
conda config --set anaconda_upload yes
conda mambabuild -c conda-forge --user ilastik-forge conda-recipe
conda build -c conda-forge --user ilastik-forge conda-recipe
10 changes: 6 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,22 @@ jobs:
auto-update-conda: true
auto-activate-base: true
activate-environment: ""
channel-priority: strict
miniforge-variant: Miniforge3
- name: install common dependencies
run: conda install -n base -c conda-forge -c nodefaults conda-build mamba boa -y
run: conda install -n base -c conda-forge -c nodefaults conda-build -y
- name: linux conda build test
if: matrix.os == 'ubuntu-latest'
shell: bash -l {0}
run: conda mambabuild -c conda-forge conda-recipe
run: conda build -c conda-forge conda-recipe
- name: osx test
if: matrix.os == 'macos-latest'
shell: bash -l {0}
run: conda mambabuild -c conda-forge conda-recipe
run: conda build -c conda-forge conda-recipe
- name: windows conda-build
if: matrix.os == 'windows-latest'
shell: cmd /C CALL {0}
run: conda mambabuild -c conda-forge conda-recipe
run: conda build -c conda-forge conda-recipe
# HACK: due to a bug in conda-build need to point to
# libarchive explicitly.
# https://github.com/conda/conda/issues/12563#issuecomment-1494264704
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ Run `conda install anaconda-client`. You need to be logged in to your https://an
```yaml
# common configuration for all packages defined in shared-config:
shared-config:
# backend: new in 0.4, added support for `conda` and `mamba` with `conda` being the default
backend: mamba
# backend: new in 0.4, only supports `conda` since removal of mamba support
backend: conda
# will translate to --python for every conda-build, deprecated, use pin-file
python: '3.6'
# will translate to --numpy for every conda-build, deprecated, use pin-file
Expand All @@ -61,6 +61,9 @@ shared-config:
- conda-forge
# channel to upload recipes to
destination-channel: my-personal-channel

# Choose which package type(s) are outputted. (Accepted inputs .tar.bz2 or 1, .conda or 2)
package-format: .conda
```

#### Package definitions
Expand Down Expand Up @@ -119,3 +122,11 @@ MACOSX_DEPLOYMENT_TARGET=10.9 publish-conda-stack my-recipe-specs.yaml
```

The `build-recipes.py` script parses the packages from `my-recipe-specs.yaml`, and for each package checks whether an up-to-date version is already available on the `destination-channel` listed in `my-recipe-specs.yaml`. If the packages don't yet exist in that channel set, it will build the package and upload it.


### Changelog

#### 0.6.0

* Added shared config key `package-format` which can be ``.tar.bz2` or `1`, `.conda` or `2`.
Default is ``.conda`.
2 changes: 1 addition & 1 deletion conda-recipe/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ test:
- pytest
- pytest-mock
commands:
- pytest --doctest-modules .
- pytest

about:
home: https://github.com/ilastik/publish-conda-stack
Expand Down
4 changes: 2 additions & 2 deletions dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
## Create a development environment

```bash
mamba env create --name pcs-dev --file dev/environment-dev.yml
conda env create --name pcs-dev --file dev/environment-dev.yml
```

This will create an environment with the name `pcs-dev`, that can be activated with `mamba activate pcs-dev`.
This will create an environment with the name `pcs-dev`, that can be activated with `conda activate pcs-dev`.

## Automatic versioning with bumpversion

Expand Down
5 changes: 2 additions & 3 deletions dev/environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ channels:
- conda-forge
dependencies:
- anaconda-client
- argcomplete
- black
- boa
- bumpversion
- conda-build
- conda-build >=24.11.0
- conda-verify
- mamba
- mypy
- pre_commit
- pytest
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
[tool.isort]
profile = "black"

[tool.pytest.ini_options]
addopts = "--doctest-modules"

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
install_requires=[
"anaconda-client",
"argcomplete",
"conda-build>=3.18.10",
"conda-build>=24.11.0",
"ruamel.yaml>=0.15.2",
],
entry_points={
Expand Down
28 changes: 11 additions & 17 deletions src/publish_conda_stack/cmdutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,27 @@


class CondaCommand(IntEnum):
RENDER: int = auto()
SEARCH: int = auto()
BUILD: int = auto()
RENDER = auto()
SEARCH = auto()
BUILD = auto()


def conda_cmd_base(command: CondaCommand, shared_config: dict) -> List[str]:
variant_config = shared_config.get("master-conda-build-config", None)
variant_args = ["-m", variant_config] if variant_config else []

# render is not supported in mamba, here we must use conda
backend = shared_config.get("backend", DEFAULT_BACKEND)
if backend not in ["conda"]:
raise ValueError(f"Unknown backend: {backend}. Only `conda` is supported.")

args = [backend]

if command == CondaCommand.RENDER:
args = ["conda"]
args.extend(["render", "--output"])
args.extend(shared_config["conda-source-channel-list"])
args.extend(variant_args)
return args

backend = shared_config.get("backend", DEFAULT_BACKEND)
if backend not in ["conda", "mamba"]:
raise ValueError(
f"Unknown backend: {backend}. Only `conda` and `mamba` are supported."
)

args = [backend]

if command == CondaCommand.SEARCH:
labels = shared_config.get("labels", [])
args.extend(
Expand All @@ -48,12 +44,10 @@ def conda_cmd_base(command: CondaCommand, shared_config: dict) -> List[str]:
return args

if command == CondaCommand.BUILD:
if backend == "mamba":
args = ["conda", "mambabuild"]
else:
args.extend(["build"])
args.extend(["build"])
args.extend(shared_config["conda-source-channel-list"])
args.extend(variant_args)
args.extend(["--package-format", shared_config["package-format"]])
return args

raise ValueError(f"unknown command supplied. Got {command}")
17 changes: 13 additions & 4 deletions src/publish_conda_stack/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@

from . import __version__
from .cmdutil import CondaCommand, conda_cmd_base
from .util import labels_to_upload_string, strip_label
from .util import (
CONDA_PACKAGE_EXTENSIONS,
labels_to_upload_string,
strip_conda_package_ext,
strip_label,
)

logger = logging.getLogger()
logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)
Expand Down Expand Up @@ -173,6 +178,9 @@ def parse_specs(args):
f"Backend must be either `conda` or `mamba` - found {shared_config['backend']}"
)

if "package-format" not in shared_config:
shared_config["package-format"] = ".conda"

logger.info(
f"Using `{shared_config['backend']}` backend. Can be set in config file under the 'backend' key."
)
Expand Down Expand Up @@ -201,6 +209,7 @@ def main():
result = {
"version": __version__,
"backend": shared_config["backend"],
"package-format": shared_config["package-format"],
"found": [],
"built": [],
"errors": [],
Expand Down Expand Up @@ -498,10 +507,10 @@ def get_rendered_version(
).decode()

rendered_filenames = [
x for x in subprocess_output.split() if x.endswith(".tar.bz2")
x for x in subprocess_output.split() if x.endswith(CONDA_PACKAGE_EXTENSIONS)
]
name_version_builds = [
CCPkgName(*Path(x).name.replace(".tar.bz2", "").rsplit("-", maxsplit=2))
CCPkgName(*strip_conda_package_ext(Path(x).name).rsplit("-", maxsplit=2))
for x in rendered_filenames
]

Expand Down Expand Up @@ -590,7 +599,7 @@ def upload_package(
"""
package_paths = []
for c_pkg_name in c_pkg_names:
pkg_file_name = f"{c_pkg_name.package_name}-{c_pkg_name.version}-{c_pkg_name.build_string}.tar.bz2"
pkg_file_name = f"{c_pkg_name.package_name}-{c_pkg_name.version}-{c_pkg_name.build_string}{shared_config['package-format']}"
BUILD_PKG_DIR = conda_bld_config.build_folder
CONDA_PLATFORM = f"{conda_bld_config.platform}-{conda_bld_config.arch}"
pkg_file_path = os.path.join(BUILD_PKG_DIR, CONDA_PLATFORM, pkg_file_name)
Expand Down
20 changes: 19 additions & 1 deletion src/publish_conda_stack/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from itertools import chain
from typing import List, Tuple, Union

CONDA_PACKAGE_EXTENSIONS = (".tar.bz2", ".conda")


def labels_to_upload_string(label_list: List[str]) -> str:
"""generates a string suitable for anaconda upload
Expand Down Expand Up @@ -53,10 +55,26 @@ def strip_label(channel_string: str) -> Tuple[str, Union[str, None]]:
>>> strip_label("some-channel")
('some-channel', None)
"""
regex = re.compile("/label/" + "(?P<label>[a-zA-Z0-9\-]+)" + "\Z")
regex = re.compile("/label/" + r"(?P<label>[a-zA-Z0-9\-]+)" + r"\Z")
res = regex.search(channel_string)
if res is None:
return channel_string, None
else:
label = res.groupdict()["label"]
return channel_string.split(f"/label/{label}")[0], label


def strip_conda_package_ext(file_name: str) -> str:
"""Remove the conda package extension from package file name

>>> strip_conda_package_ext("some-fancy-package-1.8.0-bld.tar.bz2")
'some-fancy-package-1.8.0-bld'
>>> strip_conda_package_ext("some-fancy-package-1.8.0-bld.conda")
'some-fancy-package-1.8.0-bld'
>>> strip_conda_package_ext("some-fancy-package-1.8.0-bld.nocondaext")
'some-fancy-package-1.8.0-bld.nocondaext'
"""
for ext in CONDA_PACKAGE_EXTENSIONS:
if file_name.endswith(ext):
return file_name.removesuffix(ext)
return file_name
33 changes: 10 additions & 23 deletions tests/test_cmdutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def minimal_shared_config():
return {
"conda-source-channel-list": ["-c", "test-forge"],
"upload-channel": "test-upload-forge",
"package-format": ".conda",
}


Expand All @@ -24,38 +25,21 @@ def test_conda_default(command, minimal_shared_config):
assert cmd_base[0] == "conda"


@pytest.mark.parametrize(
"backend",
[
"conda",
"mamba",
],
)
@pytest.mark.parametrize(
"command",
[
CondaCommand.SEARCH,
CondaCommand.BUILD,
],
)
def test_conda_backend_config(command, backend, minimal_shared_config):
minimal_shared_config.update({"backend": backend})
def test_conda_backend_config(command, minimal_shared_config):
minimal_shared_config.update({"backend": "conda"})
cmd_base = conda_cmd_base(command, minimal_shared_config)
if command == CondaCommand.BUILD and backend == "mamba":
# special case invocation of boa via conda mambabuild
assert cmd_base[0:2] == ["conda", "mambabuild"]
else:
assert cmd_base[0] == backend

assert cmd_base[0] == "conda"

@pytest.mark.parametrize(
"backend",
[
"conda",
"mamba",
],
)
def test_conda_backend_render_always_conda(backend, minimal_shared_config):

def test_conda_backend_render_always_conda(minimal_shared_config):
command = CondaCommand.RENDER
cmd_base = conda_cmd_base(command, minimal_shared_config)

Expand Down Expand Up @@ -92,7 +76,10 @@ def test_labels_added_to_search(labels, minimal_shared_config):
"test-upload-forge",
],
),
(CondaCommand.BUILD, ["conda", "build", "-c", "test-forge"]),
(
CondaCommand.BUILD,
["conda", "build", "-c", "test-forge", "--package-format", ".conda"],
),
],
)
def test_expected_command(command, expected, minimal_shared_config):
Expand Down
Loading