ci: add publish-on-release workflow for release-please recovery (#55) #135
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 | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| release-please: | |
| name: Release Please | |
| runs-on: ubuntu-latest | |
| outputs: | |
| release_created: ${{ steps.release.outputs.release_created }} | |
| tag_name: ${{ steps.release.outputs.tag_name }} | |
| steps: | |
| - uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4 | |
| id: release | |
| with: | |
| token: ${{ github.token }} | |
| config-file: .github/release-please-config.json | |
| manifest-file: .github/.release-please-manifest.json | |
| build: | |
| name: Build packages | |
| needs: release-please | |
| if: ${{ needs.release-please.outputs.release_created }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install build dependencies | |
| run: pip install build twine | |
| - name: Build all packages | |
| run: make build | |
| - name: Verify built packages | |
| run: make verify-packages | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| test: | |
| name: Test installation | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Download artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Test installation | |
| run: | | |
| DIST_DIR=$(pwd)/dist | |
| pip install --find-links "$DIST_DIR" dist/deepctl-*.whl | |
| deepctl --version | |
| mark-latest: | |
| name: Mark root release as latest | |
| needs: release-please | |
| # Re-assert latest on the root package tag (vX.Y.Z) after all sub-package | |
| # releases are created, since release-please processes them sequentially and | |
| # a sub-package release created after the root tag can steal the pointer. | |
| if: | | |
| needs.release-please.outputs.release_created == 'true' && | |
| startsWith(needs.release-please.outputs.tag_name, 'v') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Mark root release as latest | |
| run: gh release edit "${{ needs.release-please.outputs.tag_name }}" --latest --repo "${{ github.repository }}" | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| deploy-web: | |
| name: Deploy web to production | |
| needs: release-please | |
| # Only fire on root-package releases (v0.2.4, v1.0.0, …). | |
| # Sub-package tags look like deepctl-cmd-listen-v0.0.3 — skip those. | |
| if: | | |
| needs.release-please.outputs.release_created == 'true' && | |
| startsWith(needs.release-please.outputs.tag_name, 'v') | |
| uses: ./.github/workflows/web-production.yml | |
| secrets: inherit | |
| publish: | |
| name: Publish to PyPI | |
| needs: [build, test] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Publish to PyPI | |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1 | |
| with: | |
| password: ${{ secrets.PYPI_API_TOKEN }} | |
| packages-dir: dist/ | |
| skip-existing: true | |
| bump-brew-formula: | |
| name: Bump Homebrew formula | |
| needs: [release-please, publish] | |
| # Only fire on root-package releases (v0.2.4, v1.0.0, …). | |
| # Sub-package tags look like deepctl-cmd-listen-v0.0.3 — skip those. | |
| if: | | |
| needs.release-please.outputs.release_created == 'true' && | |
| startsWith(needs.release-please.outputs.tag_name, 'v') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: "3.13" | |
| - name: Wait for new deepctl version on PyPI | |
| run: | | |
| set -euo pipefail | |
| VERSION="${TAG_NAME#v}" | |
| for i in $(seq 1 30); do | |
| if pip index versions deepctl 2>&1 | grep -qE "(^|[^.0-9])${VERSION}([^.0-9]|$)"; then | |
| echo "deepctl==${VERSION} is live on PyPI" | |
| exit 0 | |
| fi | |
| echo "Waiting for deepctl==${VERSION} on PyPI (${i}/30)..." | |
| sleep 20 | |
| done | |
| echo "::error::deepctl==${VERSION} did not appear on PyPI after 10 minutes" | |
| exit 1 | |
| env: | |
| TAG_NAME: ${{ needs.release-please.outputs.tag_name }} | |
| - name: Checkout homebrew-tap | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| repository: deepgram/homebrew-tap | |
| token: ${{ secrets.CLI_TAP_SYNC_PAT }} | |
| path: homebrew-tap | |
| - name: Regenerate Formula/deepgram.rb | |
| run: | | |
| set -euo pipefail | |
| VERSION="${TAG_NAME#v}" | |
| python scripts/bump_brew_formula.py \ | |
| --version "${VERSION}" \ | |
| --formula homebrew-tap/Formula/deepgram.rb \ | |
| --python "$(command -v python3.13)" | |
| env: | |
| TAG_NAME: ${{ needs.release-please.outputs.tag_name }} | |
| - name: Open bump PR against homebrew-tap | |
| working-directory: homebrew-tap | |
| env: | |
| GH_TOKEN: ${{ secrets.CLI_TAP_SYNC_PAT }} | |
| TAG_NAME: ${{ needs.release-please.outputs.tag_name }} | |
| run: | | |
| set -euo pipefail | |
| VERSION="${TAG_NAME#v}" | |
| BRANCH="bump-deepctl-${VERSION}" | |
| # Attribute the bump commit to whoever owns CLI_TAP_SYNC_PAT so the | |
| # homebrew-tap PR has a clear, linkable author. Using ${{ github.actor }} | |
| # would misattribute to release-please[bot] (the workflow trigger), | |
| # not the credential owner who actually authorized the push. | |
| PAT_LOGIN=$(gh api /user --jq .login) | |
| PAT_ID=$(gh api /user --jq .id) | |
| git config user.name "${PAT_LOGIN}" | |
| git config user.email "${PAT_ID}+${PAT_LOGIN}@users.noreply.github.com" | |
| git checkout -b "${BRANCH}" | |
| if git diff --quiet -- Formula/deepgram.rb; then | |
| echo "::warning::Formula/deepgram.rb already at ${VERSION}; nothing to bump" | |
| exit 0 | |
| fi | |
| git add Formula/deepgram.rb | |
| git commit -m "Bump deepctl to ${VERSION}" | |
| git push -u origin "${BRANCH}" | |
| BODY_FILE="$(mktemp)" | |
| cat > "${BODY_FILE}" <<EOF | |
| Automated bump from [deepgram/cli@${TAG_NAME}](https://github.com/deepgram/cli/releases/tag/${TAG_NAME}). | |
| Generated by \`scripts/bump_brew_formula.py\` against PyPI metadata for \`deepctl==${VERSION}\`. Resource blocks regenerated via \`homebrew-pypi-poet\`. | |
| If this PR breaks \`brew test\` or \`brew install\`, do not edit the formula directly — the file is auto-generated. Fix the template in [\`scripts/templates/deepgram.rb.template\`](https://github.com/deepgram/cli/blob/main/scripts/templates/deepgram.rb.template) and let the next release regenerate it. For emergency fixes, run \`scripts/bump_brew_formula.py\` locally and push directly. | |
| EOF | |
| gh pr create \ | |
| --base main \ | |
| --head "${BRANCH}" \ | |
| --title "Bump deepctl to ${VERSION}" \ | |
| --body-file "${BODY_FILE}" |