Publish package (manual) #21
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 package (manual) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| confirm: | |
| description: "Confirm publish package" | |
| required: true | |
| type: boolean | |
| docs_only: | |
| description: "Only publish documentation (skip package publish)" | |
| required: false | |
| type: boolean | |
| default: false | |
| jobs: | |
| guard-ci-success: | |
| runs-on: windows-2022 | |
| permissions: | |
| contents: read | |
| statuses: read | |
| actions: read | |
| steps: | |
| - name: Ensure CI for this commit succeeded | |
| shell: pwsh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| $ownerRepo = $env:GITHUB_REPOSITORY | |
| $sha = $env:GITHUB_SHA | |
| $headers = @{ | |
| Authorization = "token $env:GITHUB_TOKEN" | |
| Accept = 'application/vnd.github+json' | |
| 'X-GitHub-Api-Version' = '2022-11-28' | |
| } | |
| # Query specific CI workflow runs and require a successful run for this commit | |
| $workflow = 'ci.yml' | |
| $branch = $env:GITHUB_REF_NAME | |
| $url = "https://api.github.com/repos/$ownerRepo/actions/workflows/$workflow/runs?branch=$branch&per_page=20" | |
| try { | |
| $resp = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ErrorAction Stop | |
| } catch { | |
| Write-Error "Blocking publish: failed to query CI workflow runs ($($_.Exception.Message))" | |
| exit 1 | |
| } | |
| if (-not $resp.workflow_runs) { | |
| Write-Error "Blocking publish: no CI runs found on branch '$branch'" | |
| exit 1 | |
| } | |
| $matching = $resp.workflow_runs | Where-Object { $_.head_sha -eq $sha -and $_.status -eq 'completed' } | |
| if (-not $matching) { | |
| Write-Error "Blocking publish: no completed CI run found for commit $sha" | |
| exit 1 | |
| } | |
| $success = $matching | Where-Object { $_.conclusion -eq 'success' } | Select-Object -First 1 | |
| if (-not $success) { | |
| $concl = ($matching | Select-Object -First 1).conclusion | |
| Write-Error "Blocking publish: CI conclusion for $sha is '$concl'" | |
| exit 1 | |
| } | |
| build-and-publish: | |
| needs: guard-ci-success | |
| if: ${{ github.event.inputs.confirm == 'true' && startsWith(github.ref_name, 'release/') }} | |
| runs-on: windows-2022 | |
| permissions: | |
| contents: write | |
| pages: write | |
| id-token: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 # Fetch all history for sphinx-multiversion | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.13' | |
| - name: Install dependencies for docs | |
| if: ${{ github.event.inputs.docs_only == 'true' }} | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Check if version exists on PyPI | |
| id: pypi_check | |
| shell: pwsh | |
| if: ${{ github.event.inputs.docs_only != 'true' }} | |
| run: | | |
| $packageName = 'moldflow' | |
| try { | |
| $resp = Invoke-WebRequest -Uri "https://pypi.org/pypi/$packageName/json" -UseBasicParsing -ErrorAction Stop | |
| $data = $resp.Content | ConvertFrom-Json | |
| $versions = @($data.releases.PSObject.Properties.Name) | |
| } catch { | |
| $versions = @() | |
| } | |
| $versionJson = Get-Content -Raw -Path version.json | ConvertFrom-Json | |
| $patch = if ($env:BUILD_NUMBER) { $env:BUILD_NUMBER } else { "$($versionJson.patch)" } | |
| $version = "$($versionJson.major).$($versionJson.minor).$patch" | |
| $exists = if ($versions -contains $version) { 'true' } else { 'false' } | |
| Write-Output "Release $version exists on PyPI: $exists" | |
| "exists=$exists" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 | |
| "version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 | |
| - name: Skip publish, version already exists | |
| if: ${{ github.event.inputs.docs_only != 'true' && steps.pypi_check.outputs.exists == 'true' }} | |
| run: Write-Output "Version ${{ steps.pypi_check.outputs.version }} already exists on PyPI. Skipping publish." | |
| - name: Install build dependencies | |
| if: ${{ github.event.inputs.docs_only != 'true' && steps.pypi_check.outputs.exists == 'false' }} | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Build package | |
| if: ${{ github.event.inputs.docs_only != 'true' && steps.pypi_check.outputs.exists == 'false' }} | |
| run: | | |
| python run.py build | |
| - name: Publish to PyPI | |
| if: ${{ github.event.inputs.docs_only != 'true' && steps.pypi_check.outputs.exists == 'false' }} | |
| env: | |
| TWINE_USERNAME: __token__ | |
| TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} | |
| run: | | |
| python run.py publish --skip-build | |
| - name: Create GitHub Release | |
| if: ${{ github.event.inputs.docs_only != 'true' && steps.pypi_check.outputs.exists == 'false' }} | |
| run: | | |
| python run.py release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Configure Pages | |
| uses: actions/configure-pages@v5 | |
| - name: Fetch Git tags | |
| run: git fetch --tags | |
| - name: Build documentation | |
| run: python run.py build-docs | |
| - name: Upload Pages artifact | |
| uses: actions/upload-pages-artifact@v4 | |
| with: | |
| path: ./docs/build/html | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 |