Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ae59566
improve some metadata for packaging purposes
bpkroth Jan 8, 2024
ad210d9
add some comments about the keyvault secrets configs
bpkroth Jan 8, 2024
de9821a
remove reference to an old file
bpkroth Jan 8, 2024
2d8aeab
comments
bpkroth Jan 8, 2024
0cb681f
Bump version: 0.1.0 → 0.2.0
bpkroth Jan 8, 2024
1b5fcc6
improvements on readme
bpkroth Jan 8, 2024
29eaefb
Bump version: 0.2.0 → 0.2.1
bpkroth Jan 8, 2024
944472b
initial attempts at publishing pypi packages
bpkroth Jan 8, 2024
797d6d3
fixups for when matplotlib is not installed
bpkroth Jan 8, 2024
3b40ded
Bump version: 0.2.1 → 0.2.2
bpkroth Jan 8, 2024
abf48ad
fixups
bpkroth Jan 8, 2024
919fd95
Revert "Bump version: 0.2.1 → 0.2.2"
bpkroth Jan 8, 2024
74037fc
tweak
bpkroth Jan 8, 2024
ec793a4
Bump version: 0.2.1 → 0.2.2
bpkroth Jan 8, 2024
eaa8e64
fixups
bpkroth Jan 8, 2024
07c60fb
Add rules for publishing packages
bpkroth Jan 8, 2024
90f550f
need the extra file for the container build
bpkroth Jan 8, 2024
3284c42
pylint fixups
bpkroth Jan 8, 2024
4b39ff8
don't require the readme to rebuild the devcontainer - breaks the cache
bpkroth Jan 9, 2024
de431e9
remove explicit version numbers from the readme
bpkroth Jan 9, 2024
dee63d1
update readme
bpkroth Jan 9, 2024
46523e7
fixups
bpkroth Jan 9, 2024
857f635
tweaks
bpkroth Jan 9, 2024
241f749
link fixup
bpkroth Jan 9, 2024
8993a67
fixups
bpkroth Jan 9, 2024
d45293f
also tag devcontainers
bpkroth Jan 9, 2024
59b471f
cosmetic
bpkroth Jan 9, 2024
9124792
FIXME: increase rebuild timeout
bpkroth Jan 9, 2024
7c58d23
testing
bpkroth Jan 9, 2024
e42b1ce
to avoid file overwrites only execute on tag pushes, not release
bpkroth Jan 9, 2024
7734d31
comments
bpkroth Jan 9, 2024
b3ffe04
add a sanity check on the tag
bpkroth Jan 9, 2024
17f830d
add notes for making a release
bpkroth Jan 9, 2024
a40f4ed
notes
bpkroth Jan 9, 2024
75bb8cb
Bump version: 0.2.2 → 0.2.3
bpkroth Jan 9, 2024
988fa56
readme updates
bpkroth Jan 9, 2024
34a8944
debugging
bpkroth Jan 9, 2024
60c1643
fixup
bpkroth Jan 9, 2024
136abe9
remove testing
bpkroth Jan 9, 2024
16cf5a8
Bump version: 0.2.3 → 0.2.4
bpkroth Jan 9, 2024
405b033
Merge branch 'main' into pypi-packaging
bpkroth Jan 9, 2024
e7defbd
Update Makefile
bpkroth Jan 9, 2024
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: 1 addition & 5 deletions .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
[bumpversion]
current_version = 0.1.0
current_version = 0.2.4
commit = True
tag = True

[bumpversion:file:README.md]

[bumpversion:file:doc/source/installation.rst]

[bumpversion:file:doc/source/conf.py]

[bumpversion:file:mlos_core/_version.py]
Expand Down
64 changes: 55 additions & 9 deletions .github/workflows/devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ on:
default: false
required: false
push:
tags: ["v*"]
branches: [ main ]
pull_request:
branches: [ main ]
Expand Down Expand Up @@ -46,6 +47,17 @@ jobs:
echo COMMIT_MESSAGES_EOF
} >> $GITHUB_OUTPUT

- name: Validate tag
if: github.ref_type == 'tag'
# Note: May need to update this for release branches in the future too.
run: |
set -x
git fetch --deepen=100
if ! git branch -a --contains ${{ github.ref_name }} | grep origin/main; then
echo "ERROR: tag ${{ github.ref_name }} doesn't appear to be included in the main branch." >&2
exit 1
fi

- name: Set NO_CACHE variable based on commit messages and for nightly builds
if: github.event_name == 'schedule' || contains(steps.get-commit-messages.outputs.COMMIT_MESSAGES, 'NO_CACHE=true') || github.event.inputs.NO_CACHE == 'true'
run: |
Expand Down Expand Up @@ -144,7 +156,9 @@ jobs:
docker exec --user vscode --env USER=vscode mlos-devcontainer make CONDA_INFO_LEVEL=-v dist dist-test

- name: Test rebuilding the devcontainer in the devcontainer
timeout-minutes: 3
# FIXME:
# timeout-minutes: 3
timeout-minutes: 10
run: |
set -x
git --no-pager diff --exit-code
Expand All @@ -157,6 +171,24 @@ jobs:
# Make sure we can publish the coverage report.
rm -f doc/build/html/htmlcov/.gitignore

- name: Publish package to Test PyPi
if: github.ref_type == 'tag'
run: |
if [ -n "${{ secrets.PYPI_TEST_USERNAME }}" ]; then
docker exec --user vscode --env USER=vscode --env MAKEFLAGS=-Oline \
--env TWINE_USERNAME=${{ secrets.PYPI_TEST_USERNAME }} --env TWINE_PASSWORD=${{ secrets.PYPI_TEST_PASSWORD }} \
mlos-devcontainer make CONDA_INFO_LEVEL=-v publish-test-pypi
fi

- name: Publish package to PyPi
if: github.repository == 'microsoft/mlos' && github.ref_type == 'tag'
run: |
if [ -n "${{ secrets.PYPI_USERNAME }}" ]; then
docker exec --user vscode --env USER=vscode --env MAKEFLAGS=-Oline \
--env TWINE_USERNAME=${{ secrets.PYPI_USERNAME }} --env TWINE_PASSWORD=${{ secrets.PYPI_PASSWORD }} \
mlos-devcontainer make CONDA_INFO_LEVEL=-v publish-pypi
fi

- name: Deploy to GitHub pages
if: github.ref == 'refs/heads/main'
uses: JamesIves/github-pages-deploy-action@v4
Expand All @@ -172,20 +204,34 @@ jobs:
docker rm --force mlos-devcontainer || true

- name: Container Registry Login
if: github.repository == 'microsoft/mlos' && github.ref == 'refs/heads/main'
if: (github.repository == 'microsoft/mlos') && (github.ref == 'refs/heads/main' || github.ref_type == 'tag')
uses: docker/login-action@v3
with:
# This is the URL of the container registry, which is configured in Github
# Settings and currently corresponds to the mlos-core ACR.
registry: ${{ secrets.ACR_LOGINURL }}
username: ${{ secrets.ACR_USERNAME }}
# This secret is configured in Github Settings.
# It can also be obtained in a keyvault in the Azure portal alongside the
# other resources used.
password: ${{ secrets.ACR_PASSWORD }}
- name: Publish the container images
if: github.repository == 'microsoft/mlos' && github.ref == 'refs/heads/main'
if: (github.repository == 'microsoft/mlos') && (github.ref == 'refs/heads/main' || github.ref_type == 'tag')
timeout-minutes: 15
# We only push to the :latest tag, to avoid needing to cleanup the
# registry manually (there's currently no API for that).
run: |
set -x
docker tag devcontainer-cli:latest ${{ secrets.ACR_LOGINURL }}/devcontainer-cli:latest
docker push ${{ secrets.ACR_LOGINURL }}/devcontainer-cli:latest
docker tag mlos-devcontainer:latest ${{ secrets.ACR_LOGINURL }}/mlos-devcontainer:latest
docker push ${{ secrets.ACR_LOGINURL }}/mlos-devcontainer:latest
image_tag=''
if [ "${{ github.ref }}" == 'refs/heads/main' ]; then
image_tag='latest'
elif [ "${{ github.ref_type }}" == 'tag' ]; then
image_tag="${{ github.ref_name }}"
fi
if [ -z "$image_tag" ]; then
echo "ERROR: Unhandled event condition or ref: event=${{ github.event}}, ref=${{ github.ref }}, ref_type=${{ github.ref_type }}"
exit 1
fi

docker tag devcontainer-cli:latest ${{ secrets.ACR_LOGINURL }}/devcontainer-cli:$image_tag
docker push ${{ secrets.ACR_LOGINURL }}/devcontainer-cli:$image_tag
docker tag mlos-devcontainer:latest ${{ secrets.ACR_LOGINURL }}/mlos-devcontainer:$image_tag
docker push ${{ secrets.ACR_LOGINURL }}/mlos-devcontainer:$image_tag
27 changes: 26 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Simply open the project in VSCode and follow the prompts to build and open the d
conda activate mlos
```

## Details
### Details

[`main`](https://github.com/microsoft/MLOS/tree/main) is considered the primary development branch.

Expand All @@ -74,6 +74,31 @@ We expect development to follow a typical "forking" style workflow:
4. PRs are associated with [Github Issues](https://github.com/microsoft/MLOS/issues) and need [MLOS-committers](https://github.com/orgs/microsoft/teams/MLOS-committers) to sign-off (in addition to other CI pipeline checks like tests and lint checks to pass).
5. Once approved, the PR can be completed using a squash merge in order to keep a nice linear history.

## Distributing

You can also locally build and install from wheels like so:

1. Build the *wheel* file(s)

```sh
make dist
```

2. Install it.

```sh
# this will install just the optimizer component with SMAC support:
pip install "dist/tmp/mlos_core-latest-py3-none-any.whl[smac]"
```

```sh
# this will install both the optimizer and the experiment runner:
pip install "dist/mlos_bench-latest-py3-none-any.whl[azure]"
```

> Note: exact versions may differ due to automatic versioning so the `-latest-` part is a symlink.
> If distributing elsewhere, adjust for the current version number in the module's `dist` directory.

### See Also

- <https://docs.github.com/en/get-started/quickstart/fork-a-repo>
Expand Down
55 changes: 55 additions & 0 deletions MAINTAINING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Maintaining

Some notes for maintainers.

## Releasing

1. Bump the version using the [`update-version.sh`](./scripts/update-version.sh) script:

```sh
git checkout -b bump-version main
./scripts/update-version.sh patch # or minor or major
```

> This will create a commit and local git tag for that version.
> You won't be able to create a release from that, so don't push it.

2. Test it!

```sh
make dist-test

# Make sure that the version number on the wheels looks correct.
ls */dist/*.whl
```

3. Make and merge a PR.

4. Update the tag locally.

Once the PR with the new version files is merged.

```sh
git checkout main
git pull
git tag vM.m.p
```

> Note: `M.m.p` is the version number you just bumped to above.

5. Retest!

```sh
make dist-clean
make dist-test
```

6. Update the tag remotely.

```sh
git push --tags
```

> Once this is done, the rules in [`.github/workflows/devcontainer.yml`](./.github/workflows/devcontainer.yml) will automatically publish the wheels to [pypi](https://pypi.org/project/mlos-core/) and tagged docker images to ACR.
> \
> Note: This may fail if the version number is already published to pypi, in which case start from the beginning.
28 changes: 27 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ mlos_bench/dist/tmp/mlos-bench-latest.tar: PACKAGE_NAME := mlos-bench
# Check to make sure the mlos_bench module has the config directory.
[ "$(MODULE_NAME)" != "mlos_bench" ] || unzip -t $(MODULE_NAME)/dist/$(MODULE_NAME)-*-py3-none-any.whl | grep -m1 mlos_bench/config/
cd $(MODULE_NAME)/dist/tmp && ln -s ../$(MODULE_NAME)-*-py3-none-any.whl $(MODULE_NAME)-latest-py3-none-any.whl
# Check to make sure the README contents made it into the package metadata.
unzip -p $(MODULE_NAME)/dist/tmp/$(MODULE_NAME)-latest-py3-none-any.whl */METADATA | egrep -v '^[A-Z][a-zA-Z-]+:' | grep -q -i '^# mlos'

.PHONY: dist-test-env-clean
dist-test-env-clean:
Expand Down Expand Up @@ -279,6 +281,27 @@ dist-test-clean: dist-test-env-clean
rm -f build/dist-test-env.$(PYTHON_VERSION).build-stamp


.PHONY: publish
publish: publish-pypi

.PHONY:
publish-pypi-deps: build/publish-pypi-deps.build-stamp

build/publish-pypi-deps.${CONDA_ENV_NAME}.build-stamp: build/conda-env.${CONDA_ENV_NAME}.build-stamp
conda run -n ${CONDA_ENV_NAME} pip install -U twine
touch $@

build/publish.%.py.build-stamp: build/publish-pypi-deps.${CONDA_ENV_NAME}.build-stamp build/pytest.${CONDA_ENV_NAME}.build-stamp build/dist-test.$(PYTHON_VERSION).build-stamp build/check-doc.build-stamp build/linklint-doc.build-stamp
rm -f mlos_*/dist/*.tar.gz
ls mlos_*/dist/*.tar | xargs -I% gzip -k %
repo_name=`echo "$@" | sed -e 's|build/publish\.||' -e 's|\.py\.build-stamp||'` \
&& conda run -n ${CONDA_ENV_NAME} python3 -m twine upload --repository $$repo_name \
mlos_*/dist/mlos*-*.tar.gz mlos_*/dist/mlos*-*.whl
touch $@

publish-pypi: build/publish.pypi.py.build-stamp
publish-test-pypi: build/publish.testpypi.py.build-stamp

build/doc-prereqs.${CONDA_ENV_NAME}.build-stamp: build/conda-env.${CONDA_ENV_NAME}.build-stamp
build/doc-prereqs.${CONDA_ENV_NAME}.build-stamp: doc/requirements.txt
conda run -n ${CONDA_ENV_NAME} pip install -U -r doc/requirements.txt
Expand Down Expand Up @@ -340,7 +363,10 @@ doc/build/html/index.html: $(SPHINX_API_RST_FILES) doc/Makefile doc/copy-source-
# See check-doc

.PHONY: doc
doc: doc/build/html/.nojekyll build/check-doc.build-stamp build/linklint-doc.build-stamp
doc: doc/build/html/.nojekyll doc-test

.PHONY: doc-test
doc-test: build/check-doc.build-stamp build/linklint-doc.build-stamp

doc/build/html/htmlcov/index.html: doc/build/html/index.html
# Make the codecov html report available for the site.
Expand Down
39 changes: 17 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ MLOS is a project to enable autotuning for systems.
- [Usage Examples](#usage-examples)
- [mlos-core](#mlos-core)
- [mlos-bench](#mlos-bench)
- [Distributing](#distributing)
- [Installation](#installation)
- [See Also](#see-also)
- [Examples](#examples)

Expand Down Expand Up @@ -127,35 +127,30 @@ See Also:
- [mlos_bench/config](./mlos_bench/mlos_bench/config/) for additional configuration details.
- [sqlite-autotuning](https://github.com/Microsoft-CISL/sqlite-autotuning) for a complete external example of using MLOS to tune `sqlite`.

## Distributing
## Installation

MLOS is not [*yet*](https://github.com/microsoft/MLOS/issues/547) published on `pypi`, so until them here are some instructions for installation for usage in production or other environments.
The MLOS modules are published to [pypi](https://pypi.org) when new tags/releases are made.

1. Build the *wheel* file(s)
To install the latest release, simply run:

```sh
make dist
```
```sh
# this will install just the optimizer component with SMAC support:
pip install -U mlos-core[smac]

2. Install it (e.g. after copying it somewhere else).

```sh
# this will install just the optimizer component with SMAC support:
pip install dist/mlos_core-0.1.0-py3-none-any.whl[smac]
# this will install just the optimizer component with flaml support:
pip install -U "mlos-core[flaml]"

# this will install just the optimizer component with flaml support:
pip install dist/mlos_core-0.1.0-py3-none-any.whl[flaml]
# this will install just the optimizer component with smac and flaml support:
pip install -U "mlos-core[smac,flaml]"

# this will install just the optimizer component with smac and flaml support:
pip install dist/mlos_core-0.1.0-py3-none-any.whl[smac,flaml]
```
# this will install both the flaml optimizer and the experiment runner with azure support:
pip install -U "mlos-bench[flaml,azure]"

```sh
# this will install both the optimizer and the experiment runner:
pip install dist/mlos_bench-0.1.0-py3-none-any.whl
```
# this will install both the smac optimizer and the experiment runner with ssh support:
pip install -U "mlos-bench[smac,ssh]"
```

> Note: exact versions may differ due to automatic versioning.
Details on using a local version from git are available in [CONTRIBUTING.md](./CONTRIBUTING.md).

## See Also

Expand Down
20 changes: 12 additions & 8 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ def pytest_configure(config: pytest.Config) -> None:
"""
# Workaround some issues loading emukit in certain environments.
if os.environ.get('DISPLAY', None):
import matplotlib # pylint: disable=import-outside-toplevel
matplotlib.rcParams['backend'] = 'agg'
if is_master(config) or dict(getattr(config, 'workerinput', {}))['workerid'] == 'gw0':
# Only warn once.
warn(UserWarning('DISPLAY environment variable is set, which can cause problems in some setups (e.g. WSL). '
+ f'Adjusting matplotlib backend to "{matplotlib.rcParams["backend"]}" to compensate.'))
try:
import matplotlib # pylint: disable=import-outside-toplevel
matplotlib.rcParams['backend'] = 'agg'
if is_master(config) or dict(getattr(config, 'workerinput', {}))['workerid'] == 'gw0':
# Only warn once.
warn(UserWarning('DISPLAY environment variable is set, which can cause problems in some setups (e.g. WSL). '
+ f'Adjusting matplotlib backend to "{matplotlib.rcParams["backend"]}" to compensate.'))
except ImportError:
pass

# Create a temporary directory for sharing files between master and worker nodes.
if is_master(config):
Expand Down Expand Up @@ -72,8 +75,9 @@ def pytest_unconfigure(config: pytest.Config) -> None:
Called after all tests have completed.
"""
if is_master(config):
shared_tmp_dir = str(getattr(config, "shared_temp_dir"))
shutil.rmtree(shared_tmp_dir)
shared_tmp_dir = getattr(config, "shared_temp_dir", None)
if shared_tmp_dir:
shutil.rmtree(str(shared_tmp_dir))


@pytest.fixture(scope="session")
Expand Down
2 changes: 1 addition & 1 deletion doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
author = 'GSL'

# The full version, including alpha/beta/rc tags
release = '0.1.0'
release = '0.2.4'

try:
from setuptools_scm import get_version
Expand Down
2 changes: 1 addition & 1 deletion mlos_bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This [directory](./) contains the code for the `mlos-bench` experiment runner package.

It makes use of the `mlos-core` package for its optimizer.
It makes use of the [`mlos-core`](../mlos_core/) package for its optimizer.

## Table of Contents

Expand Down
2 changes: 1 addition & 1 deletion mlos_bench/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
"""

# NOTE: This should be managed by bumpversion.
_VERSION = '0.1.0'
_VERSION = '0.2.4'
Loading