Development Release #96
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: Development Release | |
| # Manual trigger only - creates GitHub release with artifacts and publishes to PyPI | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| bump-type: | |
| description: 'How to bump the version' | |
| required: true | |
| type: choice | |
| default: 'prerelease' | |
| options: | |
| - prerelease # 2025.3.2a13 -> 2025.3.2a14 | |
| - prepatch # 2025.3.2 -> 2025.3.3a1 | |
| - preminor # 2025.3.2 -> 2025.4.0a1 | |
| - custom # Use custom-version input | |
| custom-version: | |
| description: 'Custom version (only if bump-type is "custom", e.g., 2025.4.0b1)' | |
| required: false | |
| type: string | |
| env: | |
| DOCKER_IMAGE: gridappsd/gridappsd-python | |
| jobs: | |
| dev-release: | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/develop' | |
| permissions: | |
| contents: write | |
| packages: write | |
| steps: | |
| - name: Verify branch | |
| run: | | |
| echo "Running on branch: ${{ github.ref_name }}" | |
| if [ "${{ github.ref_name }}" != "develop" ]; then | |
| echo "Error: Development releases can only be created from the develop branch." | |
| echo "Current branch: ${{ github.ref_name }}" | |
| exit 1 | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Pixi | |
| uses: prefix-dev/setup-pixi@v0.8.1 | |
| with: | |
| pixi-version: v0.61.0 | |
| - name: Determine version | |
| id: bump-version | |
| run: | | |
| # Get current version from pixi.toml | |
| CURRENT_VERSION=$(grep '^version' pixi.toml | head -1 | sed 's/version = "\(.*\)"/\1/') | |
| echo "Current version: $CURRENT_VERSION" | |
| BUMP_TYPE="${{ inputs.bump-type }}" | |
| if [ "$BUMP_TYPE" == "custom" ]; then | |
| # Use custom version | |
| CUSTOM_VERSION="${{ inputs.custom-version }}" | |
| if [ -z "$CUSTOM_VERSION" ]; then | |
| echo "Error: custom-version is required when bump-type is 'custom'" | |
| exit 1 | |
| fi | |
| NEW_VERSION="$CUSTOM_VERSION" | |
| echo "Using custom version: $NEW_VERSION" | |
| else | |
| # Parse version components | |
| # Handle versions like 2025.3.2a13 or 2025.3.2 | |
| if [[ $CURRENT_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(a([0-9]+))?$ ]]; then | |
| MAJOR="${BASH_REMATCH[1]}" | |
| MINOR="${BASH_REMATCH[2]}" | |
| PATCH="${BASH_REMATCH[3]}" | |
| PRE_NUM="${BASH_REMATCH[5]:-0}" | |
| else | |
| echo "Error: Cannot parse version $CURRENT_VERSION" | |
| exit 1 | |
| fi | |
| case $BUMP_TYPE in | |
| prerelease) | |
| NEW_PRE=$((PRE_NUM + 1)) | |
| NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}a${NEW_PRE}" | |
| ;; | |
| prepatch) | |
| NEW_PATCH=$((PATCH + 1)) | |
| NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}a1" | |
| ;; | |
| preminor) | |
| NEW_MINOR=$((MINOR + 1)) | |
| NEW_VERSION="${MAJOR}.${NEW_MINOR}.0a1" | |
| ;; | |
| esac | |
| fi | |
| echo "New version: $NEW_VERSION" | |
| echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV | |
| echo "NEW_TAG=v$NEW_VERSION" >> $GITHUB_ENV | |
| # Update version in pixi.toml | |
| sed -i "s/^version = \".*\"/version = \"$NEW_VERSION\"/" pixi.toml | |
| # Update version in sub-project pyproject.toml files | |
| sed -i "s/^version = \".*\"/version = \"$NEW_VERSION\"/" gridappsd-python-lib/pyproject.toml | |
| sed -i "s/^version = \".*\"/version = \"$NEW_VERSION\"/" gridappsd-field-bus-lib/pyproject.toml | |
| - name: Update lock file | |
| run: pixi install | |
| - name: Run tests | |
| run: pixi run test-all | |
| - name: Build packages | |
| run: pixi run build | |
| - name: Commit and tag | |
| run: | | |
| git config --global user.name 'github-actions[bot]' | |
| git config --global user.email 'github-actions[bot]@users.noreply.github.com' | |
| git add pixi.toml gridappsd-python-lib/pyproject.toml gridappsd-field-bus-lib/pyproject.toml | |
| git commit -m "Bump version to ${{ env.NEW_VERSION }}" | |
| git tag ${{ env.NEW_TAG }} | |
| git push origin HEAD:${{ github.ref_name }} | |
| git push origin ${{ env.NEW_TAG }} | |
| - name: Publish to PyPI | |
| if: github.repository_owner == 'GRIDAPPSD' | |
| env: | |
| TWINE_USERNAME: __token__ | |
| TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} | |
| run: pixi run publish | |
| - name: Create GitHub Release | |
| uses: ncipollo/release-action@v1.15.0 | |
| with: | |
| artifacts: "dist/*.tar.gz,dist/*.whl" | |
| artifactErrorsFailBuild: true | |
| generateReleaseNotes: true | |
| prerelease: true | |
| tag: ${{ env.NEW_TAG }} | |
| name: "Development Release ${{ env.NEW_VERSION }}" | |
| body: | | |
| ## Development Release | |
| This is a development/pre-release version published to PyPI. | |
| ### Installation | |
| **Via pip (from PyPI):** | |
| ```bash | |
| pip install gridappsd-python==${{ env.NEW_VERSION }} | |
| ``` | |
| **Via pip (from GitHub release):** | |
| ```bash | |
| pip install https://github.com/GRIDAPPSD/gridappsd-python/releases/download/${{ env.NEW_TAG }}/gridappsd_python-${{ env.NEW_VERSION }}-py3-none-any.whl | |
| ``` | |
| **Via Docker:** | |
| ```bash | |
| docker pull ${{ env.DOCKER_IMAGE }}:${{ env.NEW_VERSION }} | |
| ``` | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Verify package available on PyPI | |
| if: github.repository_owner == 'GRIDAPPSD' | |
| run: | | |
| for i in $(seq 1 30); do | |
| if pip index versions gridappsd-python 2>/dev/null | grep -q "${{ env.NEW_VERSION }}" || \ | |
| pip install --dry-run --no-deps "gridappsd-python==${{ env.NEW_VERSION }}" 2>/dev/null; then | |
| echo "Package gridappsd-python==${{ env.NEW_VERSION }} is available on PyPI" | |
| exit 0 | |
| fi | |
| echo "Attempt $i/30: Package not yet available, waiting 10s..." | |
| sleep 10 | |
| done | |
| echo "Warning: Package not confirmed on PyPI after 5 minutes, proceeding anyway" | |
| # Docker build and push | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to Docker Hub | |
| if: github.repository_owner == 'GRIDAPPSD' | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_TOKEN }} | |
| # Build default image (Python 3.12) with develop tag | |
| - name: Build and push Docker image (Python 3.12 - default) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: ${{ github.repository_owner == 'GRIDAPPSD' }} | |
| build-args: | | |
| PYTHON_VERSION=3.12 | |
| GRIDAPPSD_PYTHON_VERSION==${{ env.NEW_VERSION }} | |
| tags: | | |
| ${{ env.DOCKER_IMAGE }}:${{ env.NEW_VERSION }} | |
| ${{ env.DOCKER_IMAGE }}:${{ env.NEW_VERSION }}-py312 | |
| ${{ env.DOCKER_IMAGE }}:develop | |
| platforms: linux/amd64,linux/arm64 | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # Build Python 3.10 variant | |
| - name: Build and push Docker image (Python 3.10) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: ${{ github.repository_owner == 'GRIDAPPSD' }} | |
| build-args: | | |
| PYTHON_VERSION=3.10 | |
| GRIDAPPSD_PYTHON_VERSION==${{ env.NEW_VERSION }} | |
| tags: | | |
| ${{ env.DOCKER_IMAGE }}:${{ env.NEW_VERSION }}-py310 | |
| platforms: linux/amd64,linux/arm64 | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # Build Python 3.11 variant | |
| - name: Build and push Docker image (Python 3.11) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: ${{ github.repository_owner == 'GRIDAPPSD' }} | |
| build-args: | | |
| PYTHON_VERSION=3.11 | |
| GRIDAPPSD_PYTHON_VERSION==${{ env.NEW_VERSION }} | |
| tags: | | |
| ${{ env.DOCKER_IMAGE }}:${{ env.NEW_VERSION }}-py311 | |
| platforms: linux/amd64,linux/arm64 | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max |