let it rip! #18
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: release | |
| on: | |
| push: | |
| branches: [ main ] | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| concurrency: release | |
| env: | |
| FORCE_PATCH_IF_NO_COMMIT_TOKEN: true | |
| IGNORE_PATHS: | | |
| resources/** | |
| assets/** | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.13' # update, someday | |
| - name: Compute bumped version (eventually, this will be 'WIPACrepo/wipac-dev-next-version-action') | |
| id: version | |
| env: | |
| FORCE_PATCH_IF_NO_COMMIT_TOKEN: ${{ env.FORCE_PATCH_IF_NO_COMMIT_TOKEN }} | |
| IGNORE_PATHS: ${{ env.IGNORE_PATHS }} | |
| run: | | |
| set -euo pipefail | |
| echo "now: $(date -u +"%Y-%m-%dT%H:%M:%S.%3N")" | |
| echo | |
| # get the latest semantic-version style tag | |
| _latest_semver_tag=$(git tag --sort=-creatordate | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -n1 || true) | |
| echo "Latest semantic-version style tag: $_latest_semver_tag" | |
| echo | |
| if [ -z "$_latest_semver_tag" ]; then | |
| echo "No previous semver tag found — using 0.0.0" | |
| echo "version=0.0.0" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| else | |
| export LATEST_SEMVER_TAG_NO_V="${_latest_semver_tag#v}" | |
| fi | |
| # get info on what's changed since that tag | |
| _that_commit=$(git rev-list -n 1 "$_latest_semver_tag") | |
| echo "Looking at what's changed since $_latest_semver_tag / $_that_commit..." | |
| echo | |
| # | |
| export CHANGED_FILES=$(git diff --name-only "$_that_commit"..HEAD) # has newlines | |
| echo "Changed files:" | |
| echo "<start>" | |
| echo "$CHANGED_FILES" | |
| echo "<end>" | |
| echo | |
| # | |
| export COMMIT_LOG=$(git log "$_that_commit"..HEAD --pretty=%B) # has newlines | |
| echo "Commit log(s) since then:" | |
| echo "<start>" | |
| echo "$COMMIT_LOG" | |
| echo "<end>" | |
| echo | |
| # get next version | |
| VERSION=$(python compute_next_version.py) | |
| echo | |
| # handle output | |
| if [ -z "$VERSION" ]; then | |
| echo "No release needed" | |
| echo "version=" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Next version: $VERSION" | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Install build tools | |
| if: steps.version.outputs.version != '' | |
| run: | | |
| set -euo pipefail | |
| echo "now: $(date -u +"%Y-%m-%dT%H:%M:%S.%3N")" | |
| python -m pip install --upgrade pip | |
| pip install build setuptools setuptools-scm | |
| - name: Build package (eventually, this will be 'WIPACrepo/wipac-dev-py-build-action') | |
| if: steps.version.outputs.version != '' | |
| run: | | |
| set -euo pipefail | |
| echo "now: $(date -u +"%Y-%m-%dT%H:%M:%S.%3N")" | |
| # Validate setuptools-scm usage | |
| if ! grep -q 'setuptools-scm' pyproject.toml; then | |
| echo "::error::setuptools-scm not found in pyproject.toml — aborting" | |
| exit 1 | |
| fi | |
| # | |
| if grep -A 5 '^\[project\]' pyproject.toml | grep -q '^version\s*='; then | |
| echo "::error::[project] version is explicitly set — must be managed by setuptools-scm" | |
| exit 1 | |
| fi | |
| # | |
| if ! grep -Eq '^\[tool\.setuptools_scm\]' pyproject.toml; then | |
| echo "::error::[tool.setuptools_scm] not found in pyproject.toml — aborting" | |
| exit 1 | |
| fi | |
| # build (tell SCM to use our version instead of detecting it) | |
| SETUPTOOLS_SCM_PRETEND_VERSION=${{ steps.version.outputs.version }} \ | |
| SETUPTOOLS_SCM_DEBUG=1 \ | |
| python -m build | |
| - name: Create GitHub Release via API (may be replaced by a GHA package) | |
| if: steps.version.outputs.version != '' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| VERSION: ${{ steps.version.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| echo "now: $(date -u +"%Y-%m-%dT%H:%M:%S.%3N")" | |
| API_URL="https://api.github.com/repos/${{ github.repository }}/releases" | |
| TAG="v${VERSION}" | |
| PAYLOAD=$(jq -n \ | |
| --arg tag_name "$TAG" \ | |
| --arg target_commitish "${{ github.sha }}" \ | |
| --arg name "Release $VERSION" \ | |
| --arg body "Automated release for commit ${{ github.sha }}" \ | |
| '{ tag_name: $tag_name, target_commitish: $target_commitish, name: $name, body: $body, draft: false, prerelease: false }') | |
| curl -sSf -X POST -H "Authorization: Bearer $GH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$PAYLOAD" "$API_URL" | |
| - name: Upload to PyPI (so simple, no GHA package needed) | |
| if: steps.version.outputs.version != '' | |
| env: | |
| TWINE_USERNAME: __token__ | |
| TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| echo "now: $(date -u +"%Y-%m-%dT%H:%M:%S.%3N")" | |
| pip install twine | |
| twine upload dist/* |