publish.yml 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # Ultralytics YOLO 🚀, AGPL-3.0 license
  2. # Publish pip package to PyPI https://pypi.org/project/ultralytics/ and Docs to https://docs.ultralytics.com
  3. name: Publish to PyPI and Deploy Docs
  4. on:
  5. push:
  6. branches: [main]
  7. workflow_dispatch:
  8. inputs:
  9. pypi:
  10. type: boolean
  11. description: Publish to PyPI
  12. docs:
  13. type: boolean
  14. description: Deploy Docs
  15. jobs:
  16. publish:
  17. if: github.repository == 'ultralytics/ultralytics' && github.actor == 'glenn-jocher'
  18. name: Publish
  19. runs-on: ubuntu-latest
  20. steps:
  21. - name: Checkout code
  22. uses: actions/checkout@v3
  23. with:
  24. fetch-depth: "0" # pulls all commits (needed correct last updated dates in Docs)
  25. - name: Set up Python environment
  26. uses: actions/setup-python@v4
  27. with:
  28. python-version: '3.10'
  29. cache: 'pip' # caching pip dependencies
  30. - name: Install dependencies
  31. run: |
  32. python -m pip install --upgrade pip wheel build twine
  33. pip install -e ".[dev]" --extra-index-url https://download.pytorch.org/whl/cpu
  34. - name: Check PyPI version
  35. shell: python
  36. run: |
  37. import os
  38. import pkg_resources as pkg
  39. import ultralytics
  40. from ultralytics.utils.checks import check_latest_pypi_version
  41. v_local = pkg.parse_version(ultralytics.__version__).release
  42. v_pypi = pkg.parse_version(check_latest_pypi_version()).release
  43. print(f'Local version is {v_local}')
  44. print(f'PyPI version is {v_pypi}')
  45. d = [a - b for a, b in zip(v_local, v_pypi)] # diff
  46. increment = (d[0] == d[1] == 0) and d[2] == 1 # only publish if patch version increments by 1
  47. os.system(f'echo "increment={increment}" >> $GITHUB_OUTPUT')
  48. os.system(f'echo "version={ultralytics.__version__}" >> $GITHUB_OUTPUT')
  49. if increment:
  50. print('Local version is higher than PyPI version. Publishing new version to PyPI ✅.')
  51. id: check_pypi
  52. - name: Publish to PyPI
  53. continue-on-error: true
  54. if: (github.event_name == 'push' || github.event.inputs.pypi == 'true') && steps.check_pypi.outputs.increment == 'True'
  55. env:
  56. PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
  57. run: |
  58. python -m build
  59. python -m twine upload dist/* -u __token__ -p $PYPI_TOKEN
  60. - name: Deploy Docs
  61. continue-on-error: true
  62. if: (github.event_name == 'push' || github.event.inputs.docs == 'true') && github.repository == 'ultralytics/ultralytics' && github.actor == 'glenn-jocher'
  63. env:
  64. PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
  65. run: |
  66. mkdocs build
  67. git config --global user.name "Glenn Jocher"
  68. git config --global user.email "glenn.jocher@ultralytics.com"
  69. git clone https://github.com/ultralytics/docs.git docs-repo
  70. cd docs-repo
  71. git checkout gh-pages || git checkout -b gh-pages
  72. rm -rf *
  73. cp -R ../site/* .
  74. git add .
  75. git commit -m "Update Docs for 'ultralytics ${{ steps.check_pypi.outputs.version }}'"
  76. git push https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/ultralytics/docs.git gh-pages
  77. - name: Extract PR Details
  78. run: |
  79. if [ "${{ github.event_name }}" = "pull_request" ]; then
  80. PR_JSON=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }})
  81. PR_NUMBER=${{ github.event.pull_request.number }}
  82. PR_TITLE=$(echo $PR_JSON | jq -r '.title')
  83. else
  84. COMMIT_SHA=${{ github.event.after }}
  85. PR_JSON=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" "https://api.github.com/search/issues?q=repo:${{ github.repository }}+is:pr+is:merged+sha:$COMMIT_SHA")
  86. PR_NUMBER=$(echo $PR_JSON | jq -r '.items[0].number')
  87. PR_TITLE=$(echo $PR_JSON | jq -r '.items[0].title')
  88. fi
  89. echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
  90. echo "PR_TITLE=$PR_TITLE" >> $GITHUB_ENV
  91. - name: Notify on Slack (Success)
  92. if: success() && github.event_name == 'push' && steps.check_pypi.outputs.increment == 'True'
  93. uses: slackapi/slack-github-action@v1.24.0
  94. with:
  95. payload: |
  96. {"text": "<!channel> GitHub Actions success for ${{ github.workflow }} ✅\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* NEW 'ultralytics ${{ steps.check_pypi.outputs.version }}' pip package published 😃\n*Job Status:* ${{ job.status }}\n*Pull Request:* <https://github.com/${{ github.repository }}/pull/${{ env.PR_NUMBER }}> ${{ env.PR_TITLE }}\n"}
  97. env:
  98. SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }}
  99. - name: Notify on Slack (Failure)
  100. if: failure()
  101. uses: slackapi/slack-github-action@v1.24.0
  102. with:
  103. payload: |
  104. {"text": "<!channel> GitHub Actions error for ${{ github.workflow }} ❌\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* ${{ github.event_name }}\n*Job Status:* ${{ job.status }}\n*Pull Request:* <https://github.com/${{ github.repository }}/pull/${{ env.PR_NUMBER }}> ${{ env.PR_TITLE }}\n"}
  105. env:
  106. SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }}