Fix loaders.py broken YouTube example URLs (#15863) #1
This file contains 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
# 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 | |
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 openai 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 "version={local_version}" >> $GITHUB_OUTPUT') | |
os.system(f'echo "previous_version={online_version or "N/A"}" >> $GITHUB_OUTPUT') | |
if publish: | |
print('Ready to publish new version to PyPI ✅.') | |
id: check_pypi | |
- name: Publish new tag | |
if: (github.event_name == 'push' || github.event.inputs.pypi == 'true') && steps.check_pypi.outputs.increment == 'True' | |
run: | | |
git tag -a "v${{ steps.check_pypi.outputs.version }}" -m "$(git log -1 --pretty=%B)" # i.e. "v0.1.2 commit message" | |
git push origin "v${{ steps.check_pypi.outputs.version }}" | |
- 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.version }} | |
PREVIOUS_TAG: ${{ steps.check_pypi.outputs.previous_version }} | |
shell: python | |
run: | | |
import openai | |
import os | |
import requests | |
import json | |
import subprocess | |
# Retrieve environment variables | |
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY') | |
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN') | |
CURRENT_TAG = os.getenv('CURRENT_TAG') | |
PREVIOUS_TAG = os.getenv('PREVIOUS_TAG') | |
# Check for required environment variables | |
if not all([OPENAI_API_KEY, GITHUB_TOKEN, CURRENT_TAG, PREVIOUS_TAG]): | |
raise ValueError("One or more required environment variables are missing.") | |
latest_tag = f"v{CURRENT_TAG}" | |
previous_tag = f"v{PREVIOUS_TAG}" | |
repo = os.getenv('GITHUB_REPOSITORY') | |
headers = {"Authorization": f"token {GITHUB_TOKEN}", "Accept": "application/vnd.github.v3.diff"} | |
# Get the diff between the tags | |
url = f"https://api.github.com/repos/{repo}/compare/{previous_tag}...{latest_tag}" | |
response = requests.get(url, headers=headers) | |
diff = response.text if response.status_code == 200 else f"Failed to get diff: {response.content}" | |
# Get summary | |
messages = [ | |
{ | |
"role": "system", | |
"content": "You are an Ultralytics AI assistant skilled in software development and technical communication. Your task is to summarize GitHub releases in a way that is detailed, accurate, and understandable to both expert developers and non-expert users. Focus on highlighting the key changes and their impact in simple and intuitive terms." | |
}, | |
{ | |
"role": "user", | |
"content": f"Summarize the updates made in the '{latest_tag}' tag, focusing on major changes, their purpose, and potential impact. Keep the summary clear and suitable for a broad audience. Add emojis to enliven the summary. Reply directly with a summary along these example guidelines, though feel free to adjust as appropriate:\n\n" | |
f"## 🌟 Summary (single-line synopsis)\n" | |
f"## 📊 Key Changes (bullet points highlighting any major changes)\n" | |
f"## 🎯 Purpose & Impact (bullet points explaining any benefits and potential impact to users)\n" | |
f"\n\nHere's the release diff:\n\n{diff[:300000]}", | |
} | |
] | |
client = openai.OpenAI(api_key=OPENAI_API_KEY) | |
completion = client.chat.completions.create(model="gpt-4o-2024-08-06", messages=messages) | |
summary = completion.choices[0].message.content.strip() | |
# Get the latest commit message | |
commit_message = subprocess.run(['git', 'log', '-1', '--pretty=%B'], check=True, text=True, capture_output=True).stdout.split("\n")[0].strip() | |
# Prepare release data | |
release = { | |
'tag_name': latest_tag, | |
'name': f"{latest_tag} - {commit_message}", | |
'body': summary, | |
'draft': False, | |
'prerelease': False | |
} | |
# Create the release on GitHub | |
release_url = f"https://api.github.com/repos/{repo}/releases" | |
release_response = requests.post(release_url, headers=headers, data=json.dumps(release)) | |
if release_response.status_code == 201: | |
print(f'Successfully created release {latest_tag}') | |
else: | |
print(f'Failed to create release {latest_tag}: {release_response.content}') | |
- name: Publish to PyPI | |
continue-on-error: true | |
if: (github.event_name == 'push' || github.event.inputs.pypi == 'true') && steps.check_pypi.outputs.increment == 'True' | |
env: | |
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} | |
run: | | |
python -m build | |
python -m twine upload dist/* -u __token__ -p $PYPI_TOKEN | |
- 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 }} v${{ 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"} | |
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 }} |