Add outline navigation, per-chapter notes/review tracking, reading th… #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish to PyPI | |
| # Releases are driven by the version number, not by tags you push by hand: | |
| # every push to master (i.e. every merge) checks whether markai/__init__.py's | |
| # __version__ is already on PyPI. If it is, this workflow does nothing. If it | |
| # isn't, that version is built, tested, published, and tagged. | |
| # | |
| # So: bump __version__ in the branch, merge, and the release happens. Merge a | |
| # branch that didn't touch it and nothing ships. | |
| # | |
| # Authentication is PyPI Trusted Publishing (OIDC) — no API token is stored | |
| # anywhere. One-time setup on PyPI: project "markai" → Publishing → add a GitHub | |
| # publisher with owner "follen99", repository "MarkAI", workflow "publish.yml", | |
| # environment "pypi". | |
| on: | |
| push: | |
| branches: [master] | |
| workflow_dispatch: | |
| concurrency: | |
| group: publish-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| check: | |
| name: New version? | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.decide.outputs.version }} | |
| should_release: ${{ steps.decide.outputs.should_release }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - id: decide | |
| # Reads __version__ textually rather than importing markai, so this step | |
| # needs no dependencies installed. | |
| run: | | |
| VERSION=$(python -c "import re;print(re.search(r'__version__ = \"([^\"]+)\"', open('markai/__init__.py').read()).group(1))") | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| if curl -sfo /dev/null "https://pypi.org/pypi/markai/$VERSION/json"; then | |
| echo "should_release=false" >> "$GITHUB_OUTPUT" | |
| echo "### markai $VERSION is already on PyPI — nothing to release" >> "$GITHUB_STEP_SUMMARY" | |
| else | |
| echo "should_release=true" >> "$GITHUB_OUTPUT" | |
| echo "### Releasing markai $VERSION" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| build: | |
| name: Build and test the distributions | |
| needs: check | |
| if: needs.check.outputs.should_release == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - name: Build sdist and wheel | |
| run: | | |
| python -m pip install --upgrade pip build twine | |
| python -m build | |
| python -m twine check dist/* | |
| - name: Smoke-test the built wheel | |
| run: | | |
| python -m pip install dist/*.whl | |
| python tests/smoke_test.py | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| publish: | |
| name: Upload to PyPI | |
| needs: [check, build] | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| url: https://pypi.org/p/markai | |
| permissions: | |
| id-token: write # required for trusted publishing | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - uses: pypa/gh-action-pypi-publish@release/v1 | |
| tag: | |
| name: Tag and release notes | |
| needs: [check, publish] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create the GitHub release | |
| # After the upload, so a failed publish never leaves a tag claiming a | |
| # version that isn't on PyPI. | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| VERSION: ${{ needs.check.outputs.version }} | |
| run: | | |
| gh release create "v$VERSION" \ | |
| --target "$GITHUB_SHA" \ | |
| --title "v$VERSION" \ | |
| --generate-notes |