diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 00000000..e498046d --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,91 @@ +# Build and publish to PyPI + +on: + push: + tags: + - "v*" + pull_request: + branches: + - "main" + workflow_dispatch: + +jobs: + build_dist: + name: Build distribution 📦 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: set up python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: set up poetry + id: setup + run: | + export VENV_PATH="$HOME/venv" + python3 -m venv $VENV_PATH + source "$VENV_PATH/bin/activate" + pip install -U pip setuptools + pip install poetry + poetry config repositories.testpypi https://test.pypi.org/legacy/ + poetry build + + - name: Archive Production Artifact + uses: actions/upload-artifact@v4 + id: lmbuddy_artifacts + with: + name: lmbuddy_dists + path: dist/ + retention-days: 1 + + - name: Publish dist to test pypi + env: + POETRY_PYPI_TOKEN_TESTPYPI: ${{ secrets.PYPI_TEST_KEY }} + + if: ${{ github.event_name == 'pull_request' }} + run: | + source "$HOME/venv/bin/activate" + cd $GITHUB_WORKSPACE + echo "$GITHUB_WORKSPACE" + which poetry + poetry publish --repository testpypi + + - name: Publish dist to real pypi + env: + POETRY_PYPI_TOKEN: ${{ secrets.PYPI_KEY }} + # only runs full release if we're on main; tag filter already hit above + if: endsWith(github.event.base_ref, 'main') == true + run: | + source "$HOME/venv/bin/activate" + poetry publish + + github-release: + name: Prepare release + needs: + - build_dist + runs-on: ubuntu-latest + permissions: + contents: write # IMPORTANT: mandatory for making GitHub Releases + id-token: write # IMPORTANT: mandatory for sigstore + + steps: + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: lmbuddy_dists + path: ./dist/ + merge-multiple: true + + - name: Release Draft + uses: softprops/action-gh-release@v1 + with: + files: ./dist/* + draft: true + + - name: Release + uses: softprops/action-gh-release@v1 + # only runs full release if we're on main; tag filter already hit above + if: endsWith(github.event.base_ref, 'main') == true + with: + files: ./dist/* \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 286307de..57bc9a00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,7 +80,7 @@ For a full sample job with a directory structure that you can run with a simple [run locally to submit to the Job Submission SDK](https://docs.ray.io/en/latest/cluster/running-applications/job-submission/sdk.html#submitting-a-ray-job), see the `examples/dev_submission` directory. -## Publishing +## Publishing (manual) This section is intended for only maintainers at Mozilla.ai. Use the local installable package workflow above for iteration locally. @@ -95,10 +95,11 @@ Set up poetry to use the key(s): ``` poetry config repositories.testpypi https://test.pypi.org/legacy/ -poetry config pypi-token.testpypi $(op read "op:///PyPI-test/pypi/api_key") -poetry config pypi-token.pypi $(op read "op:///PyPI/pypi/api_key") +poetry config pypi-token.testpypi $(op read "op://mzai-dev/PyPI-test/pypi/api_key") +poetry config pypi-token.pypi $(op read "op://mzai-dev/PyPI/pypi/api_key") ``` + ### Testing publishing Then build and publish to PyPI Test: @@ -115,3 +116,44 @@ When you're ready, run: ``` poetry publish --build ``` + +## Publishing (automated) + +`.github/workflows/publish.yaml' contains the GitHub Action used to do releases and push wheels to PyPI. + +There are two subcases - draft/dev and the 'real' release. + + +### Draft / Test releases + +If a contributed opens a PR to `main` with a git version tag (e.g., `vX.Y.Z`) , the draft process will start which does the following: + +- upload a version to test PyPI +- make a draft release on github. + + +this is to ensure the full process works before merging to main. + + +### Real release + +If a commit is made to `main` with a git version tag (e.g., `vX.Y.Z`), the full process will run, and upload the package to PyPI and make a formal Release. + + +The workflow should look like the following: + +- make your changes that will be included in a release (could be a long running dev branch or otherwise) +- update the version in `pyproject.toml` +- add an annotated tag, e.g.: + * `git tag -a v1.4.0 -m "1.4.0 prepped for release; see ___ for changes"` or + * `git tag -a v1.4.3 -m "1.4.3 is a patch for issue ____"` +- push your changes to upstream +- open a PR to main +- verify that the project builds +- land PR + + + + + + diff --git a/pyproject.toml b/pyproject.toml index 4333f68a..c14d4676 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "lm-buddy" -version = "0.1.0" +version = "0.1.0rc12" description = "Ray-centric library for finetuning and evaluation of (large) language models." repository = "https://github.com/mozilla-ai/lm-buddy" readme = "README.md"