Repository navigation
update-sdk #257
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: Update and Publish SDK | |
| on: | |
| repository_dispatch: | |
| types: [update-sdk] | |
| workflow_dispatch: | |
| inputs: | |
| republish: | |
| description: "Publish a .postN release even if PyPI already has the API version (to replace a broken upload)." | |
| required: false | |
| type: boolean | |
| default: false | |
| jobs: | |
| update-and-publish: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| issues: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: python -m pip install --upgrade pip build twine | |
| - name: Install OpenAPI Generator | |
| run: npm install -g @openapitools/openapi-generator-cli | |
| - name: Choose the version to publish | |
| id: version | |
| env: | |
| REPUBLISH: ${{ github.event_name == 'workflow_dispatch' && inputs.republish || 'false' }} | |
| run: | | |
| API_VERSION=$(curl -fsS https://api.linkbreakers.com/internal/openapi/api/v1/api.swagger.json | jq -r '.info.version') | |
| echo "Swagger version: $API_VERSION" | |
| on_pypi() { | |
| CODE=$(curl -sS -o /dev/null -w '%{http_code}' "https://pypi.org/pypi/linkbreakers/$1/json") | |
| case "$CODE" in | |
| 200) return 0 ;; | |
| 404) return 1 ;; | |
| *) echo "Unexpected HTTP $CODE from PyPI" >&2; exit 1 ;; | |
| esac | |
| } | |
| PACKAGE_VERSION="$API_VERSION" | |
| if on_pypi "$API_VERSION"; then | |
| if [ "$REPUBLISH" != "true" ]; then | |
| echo "needs_update=false" >> $GITHUB_OUTPUT | |
| echo "PyPI already has $API_VERSION" | |
| exit 0 | |
| fi | |
| N=1 | |
| while on_pypi "$API_VERSION.post$N"; do N=$((N + 1)); done | |
| PACKAGE_VERSION="$API_VERSION.post$N" | |
| fi | |
| echo "needs_update=true" >> $GITHUB_OUTPUT | |
| echo "api_version=$API_VERSION" >> $GITHUB_OUTPUT | |
| echo "package_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT | |
| echo "Publishing $PACKAGE_VERSION" | |
| - name: Generate SDK | |
| if: steps.version.outputs.needs_update == 'true' | |
| env: | |
| API_VERSION: ${{ steps.version.outputs.api_version }} | |
| PACKAGE_VERSION: ${{ steps.version.outputs.package_version }} | |
| run: | | |
| curl -fsS https://api.linkbreakers.com/internal/openapi/api/v1/api.swagger.json \ | |
| | jq '.openapi = "3.1.0" | del(.jsonSchemaDialect) | .info.license = {"name": "MIT"}' > openapi-3.1.json | |
| rm -rf linkbreakers | |
| openapi-generator-cli generate \ | |
| -i openapi-3.1.json \ | |
| -g python \ | |
| -o . \ | |
| -c openapi-config.yaml \ | |
| -t templates \ | |
| --skip-validate-spec \ | |
| --git-host github.com \ | |
| --git-user-id linkbreakers-com \ | |
| --git-repo-id linkbreakers-python \ | |
| --global-property apiTests=false,modelTests=false,apiDocs=false,modelDocs=false \ | |
| --additional-properties=packageVersion=$PACKAGE_VERSION | |
| echo "$API_VERSION" > OPENAPI_VERSION | |
| rm openapi-3.1.json | |
| - name: Build distribution | |
| if: steps.version.outputs.needs_update == 'true' | |
| run: | | |
| rm -rf dist build | |
| python -m build | |
| - name: Smoke check the built package | |
| if: steps.version.outputs.needs_update == 'true' | |
| run: | | |
| python -m venv /tmp/sdk-check | |
| /tmp/sdk-check/bin/pip install dist/*.whl | |
| cd /tmp && /tmp/sdk-check/bin/python -I -c " | |
| import linkbreakers | |
| from linkbreakers import ApiClient, Configuration, LinksApi | |
| LinksApi(ApiClient(Configuration(access_token='smoke'))) | |
| " | |
| /tmp/sdk-check/bin/python -I "$GITHUB_WORKSPACE/scripts/check_docs.py" | |
| - name: Publish to PyPI | |
| if: steps.version.outputs.needs_update == 'true' | |
| env: | |
| TWINE_USERNAME: __token__ | |
| TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} | |
| run: twine upload dist/* | |
| - name: Commit, tag and push | |
| if: steps.version.outputs.needs_update == 'true' | |
| env: | |
| PACKAGE_VERSION: ${{ steps.version.outputs.package_version }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add . | |
| if ! git diff --cached --quiet; then | |
| git commit -m "chore: update SDK to version $PACKAGE_VERSION" | |
| fi | |
| git tag "v$PACKAGE_VERSION" | |
| git push --atomic origin main "v$PACKAGE_VERSION" | |
| - name: Close release failure issues | |
| if: success() && steps.version.outputs.needs_update == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PACKAGE_VERSION: ${{ steps.version.outputs.package_version }} | |
| run: | | |
| for number in $(gh issue list --repo "$GITHUB_REPOSITORY" --state open --label release-failure --json number --jq '.[].number'); do | |
| gh issue close "$number" --repo "$GITHUB_REPOSITORY" --comment "Published $PACKAGE_VERSION." | |
| done | |
| - name: Report failure | |
| if: failure() | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PACKAGE_VERSION: ${{ steps.version.outputs.package_version || 'unknown' }} | |
| RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| run: | | |
| MESSAGE="Publishing linkbreakers $PACKAGE_VERSION to PyPI failed. Run: $RUN_URL" | |
| echo "::error title=Release failed::$MESSAGE" | |
| gh label create release-failure --repo "$GITHUB_REPOSITORY" --color B60205 \ | |
| --description "The update and publish workflow failed" --force | |
| EXISTING=$(gh issue list --repo "$GITHUB_REPOSITORY" --state open --label release-failure --json number --jq '.[0].number // empty') | |
| if [ -n "$EXISTING" ]; then | |
| gh issue comment "$EXISTING" --repo "$GITHUB_REPOSITORY" --body "$MESSAGE" | |
| else | |
| gh issue create --repo "$GITHUB_REPOSITORY" --label release-failure \ | |
| --title "SDK release failing" --body "$MESSAGE" | |
| fi |