File size: 7,473 Bytes
f6228f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# Ultralytics YOLO πŸš€, AGPL-3.0 license
# Publish pip package to PyPI https://pypi.org/project/ultralytics/

name: Publish to PyPI

on:
  push:
    branches: [main]
  workflow_dispatch:
    inputs:
      pypi:
        type: boolean
        description: Publish to PyPI

jobs:
  publish:
    if: github.repository == 'ultralytics/ultralytics' && github.actor == 'glenn-jocher'
    name: Publish
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # for PyPI trusted publishing
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }} # use your PAT here
      - name: Git config
        run: |
          git config --global user.name "UltralyticsAssistant"
          git config --global user.email "[email protected]"
      - name: Set up Python environment
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"
          cache: "pip" # caching pip dependencies
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip wheel
          pip install requests build twine toml
      - name: Check PyPI version
        shell: python
        run: |
          import os
          import requests
          import toml

          # Load version and package name from pyproject.toml
          pyproject = toml.load('pyproject.toml')
          package_name = pyproject['project']['name']
          local_version = pyproject['project'].get('version', 'dynamic')

          # If version is dynamic, extract it from the specified file
          if local_version == 'dynamic':
              version_attr = pyproject['tool']['setuptools']['dynamic']['version']['attr']
              module_path, attr_name = version_attr.rsplit('.', 1)
              with open(f"{module_path.replace('.', '/')}/__init__.py") as f:
                  local_version = next(line.split('=')[1].strip().strip("'\"") for line in f if line.startswith(attr_name))

          print(f"Local Version: {local_version}")



          # Get online version from PyPI

          response = requests.get(f"https://pypi.org/pypi/{package_name}/json")
          online_version = response.json()['info']['version'] if response.status_code == 200 else None
          print(f"Online Version: {online_version or 'Not Found'}")



          # Determine if a new version should be published

          publish = False

          if online_version:

              local_ver = tuple(map(int, local_version.split('.')))

              online_ver = tuple(map(int, online_version.split('.')))

              major_diff = local_ver[0] - online_ver[0]

              minor_diff = local_ver[1] - online_ver[1]

              patch_diff = local_ver[2] - online_ver[2]



              publish = (

                  (major_diff == 0 and minor_diff == 0 and 0 < patch_diff <= 2) or

                  (major_diff == 0 and minor_diff == 1 and local_ver[2] == 0) or

                  (major_diff == 1 and local_ver[1] == 0 and local_ver[2] == 0)

              )

          else:

              publish = True  # First release



          os.system(f'echo "increment={publish}" >> $GITHUB_OUTPUT')
          os.system(f'echo "current_tag=v{local_version}" >> $GITHUB_OUTPUT')
          os.system(f'echo "previous_tag=v{online_version}" >> $GITHUB_OUTPUT')

          if publish:
              print('Ready to publish new version to PyPI βœ….')
        id: check_pypi
      - name: Build package
        if: (github.event_name == 'push' || github.event.inputs.pypi == 'true') && steps.check_pypi.outputs.increment == 'True'
        run: python -m build
      - name: Publish to PyPI
        continue-on-error: true
        if: (github.event_name == 'push' || github.event.inputs.pypi == 'true') && steps.check_pypi.outputs.increment == 'True'
        uses: pypa/gh-action-pypi-publish@release/v1
      - name: Publish new tag
        if: (github.event_name == 'push' || github.event.inputs.pypi == 'true')  && steps.check_pypi.outputs.increment == 'True'
        run: |
          git tag -a "${{ steps.check_pypi.outputs.current_tag }}" -m "$(git log -1 --pretty=%B)"  # i.e. "v0.1.2 commit message"
          git push origin "${{ steps.check_pypi.outputs.current_tag }}"
      - name: Publish new release
        if: (github.event_name == 'push' || github.event.inputs.pypi == 'true')  && steps.check_pypi.outputs.increment == 'True'
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
          CURRENT_TAG: ${{ steps.check_pypi.outputs.current_tag }}
          PREVIOUS_TAG: ${{ steps.check_pypi.outputs.previous_tag }}
        run: |
          curl -s "https://raw.githubusercontent.com/ultralytics/actions/main/utils/summarize_release.py" | python -
        shell: bash
      - name: Extract PR Details
        env:
          GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }}
        run: |
          # Check if the event is a pull request or pull_request_target
          if [ "${{ github.event_name }}" = "pull_request" ] || [ "${{ github.event_name }}" = "pull_request_target" ]; then
            PR_NUMBER=${{ github.event.pull_request.number }}
            PR_TITLE=$(gh pr view $PR_NUMBER --json title --jq '.title')
          else
            # Use gh to find the PR associated with the commit
            COMMIT_SHA=${{ github.event.after }}
            PR_JSON=$(gh pr list --search "${COMMIT_SHA}" --state merged --json number,title --jq '.[0]')
            PR_NUMBER=$(echo $PR_JSON | jq -r '.number')
            PR_TITLE=$(echo $PR_JSON | jq -r '.title')
          fi
          echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
          echo "PR_TITLE=$PR_TITLE" >> $GITHUB_ENV
      - name: Notify on Slack (Success)
        if: success() && github.event_name == 'push' && steps.check_pypi.outputs.increment == 'True'
        uses: slackapi/[email protected]
        with:
          payload: |
            {"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 '${{ github.repository }} ${{ steps.check_pypi.outputs.current_tag }}' pip package published πŸ˜ƒ\n*Job Status:* ${{ job.status }}\n*Pull Request:* <https://github.com/${{ github.repository }}/pull/${{ env.PR_NUMBER }}> ${{ env.PR_TITLE }}\n"}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }}
      - name: Notify on Slack (Failure)
        if: failure()
        uses: slackapi/[email protected]
        with:
          payload: |
            {"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"}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }}