aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml4
-rw-r--r--.github/workflows/publish.yml97
-rw-r--r--.github/workflows/release-master.yml28
-rw-r--r--.github/workflows/release-nightly.yml55
-rw-r--r--.github/workflows/release.yml346
-rw-r--r--devscripts/update-formulae.py39
-rw-r--r--devscripts/update-version.py15
-rw-r--r--devscripts/utils.py7
-rw-r--r--setup.py4
-rw-r--r--yt_dlp/update.py1
-rw-r--r--yt_dlp/version.py4
11 files changed, 362 insertions, 238 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ac0cfdf7c..c9260eeca 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -96,9 +96,7 @@ jobs:
auto-activate-base: false
- name: Install Requirements
run: |
- sudo apt-get -y install zip pandoc man sed
- python -m pip install -U pip setuptools wheel
- python -m pip install -U Pyinstaller -r requirements.txt
+ sudo apt -y install zip pandoc man sed
reqs=$(mktemp)
cat > $reqs << EOF
python=3.10.*
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index 9ebf54e7f..000000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,97 +0,0 @@
-name: Publish
-on:
- workflow_call:
- inputs:
- channel:
- default: stable
- required: true
- type: string
- version:
- required: true
- type: string
- target_commitish:
- required: true
- type: string
- prerelease:
- default: false
- required: true
- type: boolean
- secrets:
- ARCHIVE_REPO_TOKEN:
- required: false
-
-permissions:
- contents: write
-
-jobs:
- publish:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0
- - uses: actions/download-artifact@v3
- - uses: actions/setup-python@v4
- with:
- python-version: "3.10"
-
- - name: Generate release notes
- run: |
- printf '%s' \
- '[![Installation](https://img.shields.io/badge/-Which%20file%20should%20I%20download%3F-white.svg?style=for-the-badge)]' \
- '(https://github.com/yt-dlp/yt-dlp#installation "Installation instructions") ' \
- '[![Documentation](https://img.shields.io/badge/-Docs-brightgreen.svg?style=for-the-badge&logo=GitBook&labelColor=555555)]' \
- '(https://github.com/yt-dlp/yt-dlp/tree/2023.03.04#readme "Documentation") ' \
- '[![Donate](https://img.shields.io/badge/_-Donate-red.svg?logo=githubsponsors&labelColor=555555&style=for-the-badge)]' \
- '(https://github.com/yt-dlp/yt-dlp/blob/master/Collaborators.md#collaborators "Donate") ' \
- '[![Discord](https://img.shields.io/discord/807245652072857610?color=blue&labelColor=555555&label=&logo=discord&style=for-the-badge)]' \
- '(https://discord.gg/H5MNcFW63r "Discord") ' \
- ${{ inputs.channel != 'nightly' && '"[![Nightly](https://img.shields.io/badge/Get%20nightly%20builds-purple.svg?style=for-the-badge)]" \
- "(https://github.com/yt-dlp/yt-dlp-nightly-builds/releases/latest \"Nightly builds\")"' || '' }} \
- > ./RELEASE_NOTES
- printf '\n\n' >> ./RELEASE_NOTES
- cat >> ./RELEASE_NOTES << EOF
- #### A description of the various files are in the [README](https://github.com/yt-dlp/yt-dlp#release-files)
- ---
- $(python ./devscripts/make_changelog.py -vv --collapsible)
- EOF
- printf '%s\n\n' '**This is an automated nightly pre-release build**' >> ./NIGHTLY_NOTES
- cat ./RELEASE_NOTES >> ./NIGHTLY_NOTES
- printf '%s\n\n' 'Generated from: https://github.com/${{ github.repository }}/commit/${{ inputs.target_commitish }}' >> ./ARCHIVE_NOTES
- cat ./RELEASE_NOTES >> ./ARCHIVE_NOTES
-
- - name: Archive nightly release
- env:
- GH_TOKEN: ${{ secrets.ARCHIVE_REPO_TOKEN }}
- GH_REPO: ${{ vars.ARCHIVE_REPO }}
- if: |
- inputs.channel == 'nightly' && env.GH_TOKEN != '' && env.GH_REPO != ''
- run: |
- gh release create \
- --notes-file ARCHIVE_NOTES \
- --title "yt-dlp nightly ${{ inputs.version }}" \
- ${{ inputs.version }} \
- artifact/*
-
- - name: Prune old nightly release
- if: inputs.channel == 'nightly' && !vars.ARCHIVE_REPO
- env:
- GH_TOKEN: ${{ github.token }}
- run: |
- gh release delete --yes --cleanup-tag "nightly" || true
- git tag --delete "nightly" || true
- sleep 5 # Enough time to cover deletion race condition
-
- - name: Publish release${{ inputs.channel == 'nightly' && ' (nightly)' || '' }}
- env:
- GH_TOKEN: ${{ github.token }}
- if: (inputs.channel == 'nightly' && !vars.ARCHIVE_REPO) || inputs.channel != 'nightly'
- run: |
- gh release create \
- --notes-file ${{ inputs.channel == 'nightly' && 'NIGHTLY_NOTES' || 'RELEASE_NOTES' }} \
- --target ${{ inputs.target_commitish }} \
- --title "yt-dlp ${{ inputs.channel == 'nightly' && 'nightly ' || '' }}${{ inputs.version }}" \
- ${{ inputs.prerelease && '--prerelease' || '' }} \
- ${{ inputs.channel == 'nightly' && '"nightly"' || inputs.version }} \
- artifact/*
diff --git a/.github/workflows/release-master.yml b/.github/workflows/release-master.yml
new file mode 100644
index 000000000..0208b3bef
--- /dev/null
+++ b/.github/workflows/release-master.yml
@@ -0,0 +1,28 @@
+name: Release (master)
+on:
+ push:
+ branches:
+ - master
+ paths:
+ - "yt_dlp/**.py"
+ - "!yt_dlp/version.py"
+ - "setup.py"
+ - "pyinst.py"
+concurrency:
+ group: release-master
+ cancel-in-progress: true
+permissions:
+ contents: read
+
+jobs:
+ release:
+ if: vars.BUILD_MASTER != ''
+ uses: ./.github/workflows/release.yml
+ with:
+ prerelease: true
+ source: master
+ permissions:
+ contents: write
+ packages: write
+ id-token: write # mandatory for trusted publishing
+ secrets: inherit
diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml
index 543e2e6f7..947eada27 100644
--- a/.github/workflows/release-nightly.yml
+++ b/.github/workflows/release-nightly.yml
@@ -1,52 +1,35 @@
name: Release (nightly)
on:
- push:
- branches:
- - master
- paths:
- - "yt_dlp/**.py"
- - "!yt_dlp/version.py"
-concurrency:
- group: release-nightly
- cancel-in-progress: true
+ schedule:
+ - cron: '23 23 * * *'
permissions:
contents: read
jobs:
- prepare:
+ check_nightly:
if: vars.BUILD_NIGHTLY != ''
runs-on: ubuntu-latest
outputs:
- version: ${{ steps.get_version.outputs.version }}
-
+ commit: ${{ steps.check_for_new_commits.outputs.commit }}
steps:
- uses: actions/checkout@v3
- - name: Get version
- id: get_version
+ with:
+ fetch-depth: 0
+ - name: Check for new commits
+ id: check_for_new_commits
run: |
- python devscripts/update-version.py "$(date -u +"%H%M%S")" | grep -Po "version=\d+(\.\d+){3}" >> "$GITHUB_OUTPUT"
+ relevant_files=("yt_dlp/*.py" ':!yt_dlp/version.py' "setup.py" "pyinst.py")
+ echo "commit=$(git log --format=%H -1 --since="24 hours ago" -- "${relevant_files[@]}")" | tee "$GITHUB_OUTPUT"
- build:
- needs: prepare
- uses: ./.github/workflows/build.yml
+ release:
+ needs: [check_nightly]
+ if: ${{ needs.check_nightly.outputs.commit }}
+ uses: ./.github/workflows/release.yml
with:
- version: ${{ needs.prepare.outputs.version }}
- channel: nightly
- permissions:
- contents: read
- packages: write # For package cache
- secrets:
- GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
-
- publish:
- needs: [prepare, build]
- uses: ./.github/workflows/publish.yml
- secrets:
- ARCHIVE_REPO_TOKEN: ${{ secrets.ARCHIVE_REPO_TOKEN }}
+ prerelease: true
+ source: nightly
permissions:
contents: write
- with:
- channel: nightly
- prerelease: true
- version: ${{ needs.prepare.outputs.version }}
- target_commitish: ${{ github.sha }}
+ packages: write
+ id-token: write # mandatory for trusted publishing
+ secrets: inherit
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ada508be8..0e50b74e0 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,14 +1,45 @@
name: Release
on:
- workflow_dispatch:
+ workflow_call:
inputs:
+ prerelease:
+ required: false
+ default: true
+ type: boolean
+ source:
+ required: false
+ default: ''
+ type: string
+ target:
+ required: false
+ default: ''
+ type: string
version:
- description: Version tag (YYYY.MM.DD[.REV])
required: false
default: ''
type: string
- channel:
- description: Update channel (stable/nightly/...)
+ workflow_dispatch:
+ inputs:
+ source:
+ description: |
+ SOURCE of this release's updates:
+ channel, repo, tag, or channel/repo@tag
+ (default: <current_repo>)
+ required: false
+ default: ''
+ type: string
+ target:
+ description: |
+ TARGET to publish this release to:
+ channel, tag, or channel@tag
+ (default: <source> if writable else <current_repo>[@source_tag])
+ required: false
+ default: ''
+ type: string
+ version:
+ description: |
+ VERSION: yyyy.mm.dd[.rev] or rev
+ (default: auto-generated)
required: false
default: ''
type: string
@@ -26,8 +57,14 @@ jobs:
contents: write
runs-on: ubuntu-latest
outputs:
- channel: ${{ steps.set_channel.outputs.channel }}
- version: ${{ steps.update_version.outputs.version }}
+ channel: ${{ steps.setup_variables.outputs.channel }}
+ version: ${{ steps.setup_variables.outputs.version }}
+ target_repo: ${{ steps.setup_variables.outputs.target_repo }}
+ target_repo_token: ${{ steps.setup_variables.outputs.target_repo_token }}
+ target_tag: ${{ steps.setup_variables.outputs.target_tag }}
+ pypi_project: ${{ steps.setup_variables.outputs.pypi_project }}
+ pypi_suffix: ${{ steps.setup_variables.outputs.pypi_suffix }}
+ pypi_token: ${{ steps.setup_variables.outputs.pypi_token }}
head_sha: ${{ steps.get_target.outputs.head_sha }}
steps:
@@ -39,25 +76,132 @@ jobs:
with:
python-version: "3.10"
- - name: Set channel
- id: set_channel
+ - name: Process inputs
+ id: process_inputs
run: |
- CHANNEL="${{ github.repository == 'yt-dlp/yt-dlp' && 'stable' || github.repository }}"
- echo "channel=${{ inputs.channel || '$CHANNEL' }}" > "$GITHUB_OUTPUT"
+ cat << EOF
+ ::group::Inputs
+ prerelease=${{ inputs.prerelease }}
+ source=${{ inputs.source }}
+ target=${{ inputs.target }}
+ version=${{ inputs.version }}
+ ::endgroup::
+ EOF
+ IFS='@' read -r source_repo source_tag <<<"${{ inputs.source }}"
+ IFS='@' read -r target_repo target_tag <<<"${{ inputs.target }}"
+ cat << EOF >> "$GITHUB_OUTPUT"
+ source_repo=${source_repo}
+ source_tag=${source_tag}
+ target_repo=${target_repo}
+ target_tag=${target_tag}
+ EOF
- - name: Update version
- id: update_version
+ - name: Setup variables
+ id: setup_variables
+ env:
+ source_repo: ${{ steps.process_inputs.outputs.source_repo }}
+ source_tag: ${{ steps.process_inputs.outputs.source_tag }}
+ target_repo: ${{ steps.process_inputs.outputs.target_repo }}
+ target_tag: ${{ steps.process_inputs.outputs.target_tag }}
run: |
- REVISION="${{ vars.PUSH_VERSION_COMMIT == '' && '$(date -u +"%H%M%S")' || '' }}"
- REVISION="${{ inputs.prerelease && '$(date -u +"%H%M%S")' || '$REVISION' }}"
- python devscripts/update-version.py ${{ inputs.version || '$REVISION' }} | \
- grep -Po "version=\d+\.\d+\.\d+(\.\d+)?" >> "$GITHUB_OUTPUT"
+ # unholy bash monstrosity (sincere apologies)
+ fallback_token () {
+ if ${{ !secrets.ARCHIVE_REPO_TOKEN }}; then
+ echo "::error::Repository access secret ${target_repo_token^^} not found"
+ exit 1
+ fi
+ target_repo_token=ARCHIVE_REPO_TOKEN
+ return 0
+ }
+
+ source_is_channel=0
+ [[ "${source_repo}" == 'stable' ]] && source_repo='yt-dlp/yt-dlp'
+ if [[ -z "${source_repo}" ]]; then
+ source_repo='${{ github.repository }}'
+ elif [[ '${{ vars[format('{0}_archive_repo', env.source_repo)] }}' ]]; then
+ source_is_channel=1
+ source_channel='${{ vars[format('{0}_archive_repo', env.source_repo)] }}'
+ elif [[ -z "${source_tag}" && "${source_repo}" != */* ]]; then
+ source_tag="${source_repo}"
+ source_repo='${{ github.repository }}'
+ fi
+ resolved_source="${source_repo}"
+ if [[ "${source_tag}" ]]; then
+ resolved_source="${resolved_source}@${source_tag}"
+ elif [[ "${source_repo}" == 'yt-dlp/yt-dlp' ]]; then
+ resolved_source='stable'
+ fi
+
+ revision="${{ (inputs.prerelease || !vars.PUSH_VERSION_COMMIT) && '$(date -u +"%H%M%S")' || '' }}"
+ version="$(
+ python devscripts/update-version.py -c "${resolved_source}" ${{ inputs.version || '$revision' }} | \
+ grep -Po "version=\K\d+\.\d+\.\d+(\.\d+)?")"
+
+ if [[ "${target_repo}" ]]; then
+ if [[ -z "${target_tag}" ]]; then
+ if [[ '${{ vars[format('{0}_archive_repo', env.target_repo)] }}' ]]; then
+ target_tag="${source_tag:-${version}}"
+ else
+ target_tag="${target_repo}"
+ target_repo='${{ github.repository }}'
+ fi
+ fi
+ if [[ "${target_repo}" != '${{ github.repository}}' ]]; then
+ target_repo='${{ vars[format('{0}_archive_repo', env.target_repo)] }}'
+ target_repo_token='${{ env.target_repo }}_archive_repo_token'
+ ${{ !!secrets[format('{0}_archive_repo_token', env.target_repo)] }} || fallback_token
+ pypi_project='${{ vars[format('{0}_pypi_project', env.target_repo)] }}'
+ pypi_suffix='${{ vars[format('{0}_pypi_suffix', env.target_repo)] }}'
+ ${{ !secrets[format('{0}_pypi_token', env.target_repo)] }} || pypi_token='${{ env.target_repo }}_pypi_token'
+ fi
+ else
+ target_tag="${source_tag:-${version}}"
+ if ((source_is_channel)); then
+ target_repo="${source_channel}"
+ target_repo_token='${{ env.source_repo }}_archive_repo_token'
+ ${{ !!secrets[format('{0}_archive_repo_token', env.source_repo)] }} || fallback_token
+ pypi_project='${{ vars[format('{0}_pypi_project', env.source_repo)] }}'
+ pypi_suffix='${{ vars[format('{0}_pypi_suffix', env.source_repo)] }}'
+ ${{ !secrets[format('{0}_pypi_token', env.source_repo)] }} || pypi_token='${{ env.source_repo }}_pypi_token'
+ else
+ target_repo='${{ github.repository }}'
+ fi
+ fi
+
+ if [[ "${target_repo}" == '${{ github.repository }}' ]] && ${{ !inputs.prerelease }}; then
+ pypi_project='${{ vars.PYPI_PROJECT }}'
+ fi
+ if [[ -z "${pypi_token}" && "${pypi_project}" ]]; then
+ if ${{ !secrets.PYPI_TOKEN }}; then
+ pypi_token=OIDC
+ else
+ pypi_token=PYPI_TOKEN
+ fi
+ fi
+
+ echo "::group::Output variables"
+ cat << EOF | tee -a "$GITHUB_OUTPUT"
+ channel=${resolved_source}
+ version=${version}
+ target_repo=${target_repo}
+ target_repo_token=${target_repo_token}
+ target_tag=${target_tag}
+ pypi_project=${pypi_project}
+ pypi_suffix=${pypi_suffix}
+ pypi_token=${pypi_token}
+ EOF
+ echo "::endgroup::"
- name: Update documentation
+ env:
+ version: ${{ steps.setup_variables.outputs.version }}
+ target_repo: ${{ steps.setup_variables.outputs.target_repo }}
+ if: |
+ !inputs.prerelease && env.target_repo == github.repository
run: |
make doc
sed '/### /Q' Changelog.md >> ./CHANGELOG
- echo '### ${{ steps.update_version.outputs.version }}' >> ./CHANGELOG
+ echo '### ${{ env.version }}' >> ./CHANGELOG
python ./devscripts/make_changelog.py -vv -c >> ./CHANGELOG
echo >> ./CHANGELOG
grep -Poz '(?s)### \d+\.\d+\.\d+.+' 'Changelog.md' | head -n -1 >> ./CHANGELOG
@@ -65,12 +209,16 @@ jobs:
- name: Push to release
id: push_release
- if: ${{ !inputs.prerelease }}
+ env:
+ version: ${{ steps.setup_variables.outputs.version }}
+ target_repo: ${{ steps.setup_variables.outputs.target_repo }}
+ if: |
+ !inputs.prerelease && env.target_repo == github.repository
run: |
git config --global user.name github-actions
- git config --global user.email github-actions@example.com
+ git config --global user.email github-actions@github.com
git add -u
- git commit -m "Release ${{ steps.update_version.outputs.version }}" \
+ git commit -m "Release ${{ env.version }}" \
-m "Created by: ${{ github.event.sender.login }}" -m ":ci skip all :ci run dl"
git push origin --force ${{ github.event.ref }}:release
@@ -80,7 +228,10 @@ jobs:
echo "head_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Update master
- if: vars.PUSH_VERSION_COMMIT != '' && !inputs.prerelease
+ env:
+ target_repo: ${{ steps.setup_variables.outputs.target_repo }}
+ if: |
+ vars.PUSH_VERSION_COMMIT != '' && !inputs.prerelease && env.target_repo == github.repository
run: git push origin ${{ github.event.ref }}
build:
@@ -95,9 +246,12 @@ jobs:
secrets:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
- publish_pypi_homebrew:
+ publish_pypi:
needs: [prepare, build]
+ if: ${{ needs.prepare.outputs.pypi_project }}
runs-on: ubuntu-latest
+ permissions:
+ id-token: write # mandatory for trusted publishing
steps:
- uses: actions/checkout@v3
@@ -107,57 +261,137 @@ jobs:
- name: Install Requirements
run: |
- sudo apt-get -y install pandoc man
+ sudo apt -y install pandoc man
python -m pip install -U pip setuptools wheel twine
python -m pip install -U -r requirements.txt
- name: Prepare
+ env:
+ version: ${{ needs.prepare.outputs.version }}
+ suffix: ${{ needs.prepare.outputs.pypi_suffix }}
+ channel: ${{ needs.prepare.outputs.channel }}
+ target_repo: ${{ needs.prepare.outputs.target_repo }}
+ pypi_project: ${{ needs.prepare.outputs.pypi_project }}
run: |
- python devscripts/update-version.py ${{ needs.prepare.outputs.version }}
+ python devscripts/update-version.py -c "${{ env.channel }}" -r "${{ env.target_repo }}" -s "${{ env.suffix }}" "${{ env.version }}"
python devscripts/make_lazy_extractors.py
+ sed -i -E "s/(name=')[^']+(', # package name)/\1${{ env.pypi_project }}\2/" setup.py
- - name: Build and publish on PyPI
- env:
- TWINE_USERNAME: __token__
- TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
- if: env.TWINE_PASSWORD != '' && !inputs.prerelease
+ - name: Build
run: |
rm -rf dist/*
make pypi-files
python devscripts/set-variant.py pip -M "You installed yt-dlp with pip or using the wheel from PyPi; Use that to update"
python setup.py sdist bdist_wheel
- twine upload dist/*
-
- - name: Checkout Homebrew repository
- env:
- BREW_TOKEN: ${{ secrets.BREW_TOKEN }}
- PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
- if: env.BREW_TOKEN != '' && env.PYPI_TOKEN != '' && !inputs.prerelease
- uses: actions/checkout@v3
- with:
- repository: yt-dlp/homebrew-taps
- path: taps
- ssh-key: ${{ secrets.BREW_TOKEN }}
- - name: Update Homebrew Formulae
+ - name: Publish to PyPI via token
env:
- BREW_TOKEN: ${{ secrets.BREW_TOKEN }}
- PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
- if: env.BREW_TOKEN != '' && env.PYPI_TOKEN != '' && !inputs.prerelease
+ TWINE_USERNAME: __token__
+ TWINE_PASSWORD: ${{ secrets[needs.prepare.outputs.pypi_token] }}
+ if: |
+ needs.prepare.outputs.pypi_token != 'OIDC' && env.TWINE_PASSWORD
run: |
- python devscripts/update-formulae.py taps/Formula/yt-dlp.rb "${{ needs.prepare.outputs.version }}"
- git -C taps/ config user.name github-actions
- git -C taps/ config user.email github-actions@example.com
- git -C taps/ commit -am 'yt-dlp: ${{ needs.prepare.outputs.version }}'
- git -C taps/ push
+ twine upload dist/*
+
+ - name: Publish to PyPI via trusted publishing
+ if: |
+ needs.prepare.outputs.pypi_token == 'OIDC'
+ uses: pypa/gh-action-pypi-publish@release/v1
+ with:
+ verbose: true
publish:
needs: [prepare, build]
- uses: ./.github/workflows/publish.yml
permissions:
contents: write
- with:
- channel: ${{ needs.prepare.outputs.channel }}
- prerelease: ${{ inputs.prerelease }}
- version: ${{ needs.prepare.outputs.version }}
- target_commitish: ${{ needs.prepare.outputs.head_sha }}
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - uses: actions/download-artifact@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: "3.10"
+
+ - name: Generate release notes
+ env:
+ head_sha: ${{ needs.prepare.outputs.head_sha }}
+ target_repo: ${{ needs.prepare.outputs.target_repo }}
+ target_tag: ${{ needs.prepare.outputs.target_tag }}
+ run: |
+ printf '%s' \
+ '[![Installation](https://img.shields.io/badge/-Which%20file%20should%20I%20download%3F-white.svg?style=for-the-badge)]' \
+ '(https://github.com/${{ github.repository }}#installation "Installation instructions") ' \
+ '[![Documentation](https://img.shields.io/badge/-Docs-brightgreen.svg?style=for-the-badge&logo=GitBook&labelColor=555555)]' \
+ '(https://github.com/${{ github.repository }}' \
+ '${{ env.target_repo == github.repository && format('/tree/{0}', env.target_tag) || '' }}#readme "Documentation") ' \
+ '[![Donate](https://img.shields.io/badge/_-Donate-red.svg?logo=githubsponsors&labelColor=555555&style=for-the-badge)]' \
+ '(https://github.com/yt-dlp/yt-dlp/blob/master/Collaborators.md#collaborators "Donate") ' \
+ '[![Discord](https://img.shields.io/discord/807245652072857610?color=blue&labelColor=555555&label=&logo=discord&style=for-the-badge)]' \
+ '(https://discord.gg/H5MNcFW63r "Discord") ' \
+ ${{ env.target_repo == 'yt-dlp/yt-dlp' && '\
+ "[![Nightly](https://img.shields.io/badge/Get%20nightly%20builds-purple.svg?style=for-the-badge)]" \
+ "(https://github.com/yt-dlp/yt-dlp-nightly-builds/releases/latest \"Nightly builds\") " \
+ "[![Master](https://img.shields.io/badge/Get%20master%20builds-lightblue.svg?style=for-the-badge)]" \
+ "(https://github.com/yt-dlp/yt-dlp-master-builds/releases/latest \"Master builds\")"' || '' }} > ./RELEASE_NOTES
+ printf '\n\n' >> ./RELEASE_NOTES
+ cat >> ./RELEASE_NOTES << EOF
+ #### A description of the various files are in the [README](https://github.com/${{ github.repository }}#release-files)
+ ---
+ $(python ./devscripts/make_changelog.py -vv --collapsible)
+ EOF
+ printf '%s\n\n' '**This is a pre-release build**' >> ./PRERELEASE_NOTES
+ cat ./RELEASE_NOTES >> ./PRERELEASE_NOTES
+ printf '%s\n\n' 'Generated from: https://github.com/${{ github.repository }}/commit/${{ env.head_sha }}' >> ./ARCHIVE_NOTES
+ cat ./RELEASE_NOTES >> ./ARCHIVE_NOTES
+
+ - name: Publish to archive repo
+ env:
+ GH_TOKEN: ${{ secrets[needs.prepare.outputs.target_repo_token] }}
+ GH_REPO: ${{ needs.prepare.outputs.target_repo }}
+ version: ${{ needs.prepare.outputs.version }}
+ channel: ${{ needs.prepare.outputs.channel }}
+ if: |
+ inputs.prerelease && env.GH_TOKEN != '' && env.GH_REPO != '' && env.GH_REPO != github.repository
+ run: |
+ title="${{ startswith(env.GH_REPO, 'yt-dlp/') && 'yt-dlp ' || '' }}${{ env.channel }}"
+ gh release create \
+ --notes-file ARCHIVE_NOTES \
+ --title "${title} ${{ env.version }}" \
+ ${{ env.version }} \
+ artifact/*
+
+ - name: Prune old release
+ env:
+ GH_TOKEN: ${{ github.token }}
+ version: ${{ needs.prepare.outputs.version }}
+ target_repo: ${{ needs.prepare.outputs.target_repo }}
+ target_tag: ${{ needs.prepare.outputs.target_tag }}
+ if: |
+ env.target_repo == github.repository && env.target_tag != env.version
+ run: |
+ gh release delete --yes --cleanup-tag "${{ env.target_tag }}" || true
+ git tag --delete "${{ env.target_tag }}" || true
+ sleep 5 # Enough time to cover deletion race condition
+
+ - name: Publish release
+ env:
+ GH_TOKEN: ${{ github.token }}
+ version: ${{ needs.prepare.outputs.version }}
+ target_repo: ${{ needs.prepare.outputs.target_repo }}
+ target_tag: ${{ needs.prepare.outputs.target_tag }}
+ head_sha: ${{ needs.prepare.outputs.head_sha }}
+ if: |
+ env.target_repo == github.repository
+ run: |
+ title="${{ github.repository == 'yt-dlp/yt-dlp' && 'yt-dlp ' || '' }}"
+ title+="${{ env.target_tag != env.version && format('{0} ', env.target_tag) || '' }}"
+ gh release create \
+ --notes-file ${{ inputs.prerelease && 'PRERELEASE_NOTES' || 'RELEASE_NOTES' }} \
+ --target ${{ env.head_sha }} \
+ --title "${title}${{ env.version }}" \
+ ${{ inputs.prerelease && '--prerelease' || '' }} \
+ ${{ env.target_tag }} \
+ artifact/*
diff --git a/devscripts/update-formulae.py b/devscripts/update-formulae.py
deleted file mode 100644
index e79297f53..000000000
--- a/devscripts/update-formulae.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python3
-
-"""
-Usage: python3 ./devscripts/update-formulae.py <path-to-formulae-rb> <version>
-version can be either 0-aligned (yt-dlp version) or normalized (PyPi version)
-"""
-
-# Allow direct execution
-import os
-import sys
-
-sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-
-import json
-import re
-import urllib.request
-
-from devscripts.utils import read_file, write_file
-
-filename, version = sys.argv[1:]
-
-normalized_version = '.'.join(str(int(x)) for x in version.split('.'))
-
-pypi_release = json.loads(urllib.request.urlopen(
- 'https://pypi.org/pypi/yt-dlp/%s/json' % normalized_version
-).read().decode())
-
-tarball_file = next(x for x in pypi_release['urls'] if x['filename'].endswith('.tar.gz'))
-
-sha256sum = tarball_file['digests']['sha256']
-url = tarball_file['url']
-
-formulae_text = read_file(filename)
-
-formulae_text = re.sub(r'sha256 "[0-9a-f]*?"', 'sha256 "%s"' % sha256sum, formulae_text, count=1)
-formulae_text = re.sub(r'url "[^"]*?"', 'url "%s"' % url, formulae_text, count=1)
-
-write_file(filename, formulae_text)
diff --git a/devscripts/update-version.py b/devscripts/update-version.py
index 0144bd284..da54a6a25 100644
--- a/devscripts/update-version.py
+++ b/devscripts/update-version.py
@@ -20,7 +20,7 @@ def get_new_version(version, revision):
version = datetime.now(timezone.utc).strftime('%Y.%m.%d')
if revision:
- assert revision.isdigit(), 'Revision must be a number'
+ assert revision.isdecimal(), 'Revision must be a number'
else:
old_version = read_version().split('.')
if version.split('.') == old_version[:3]:
@@ -46,6 +46,10 @@ VARIANT = None
UPDATE_HINT = None
CHANNEL = {channel!r}
+
+ORIGIN = {origin!r}
+
+_pkg_version = {package_version!r}
'''
if __name__ == '__main__':
@@ -54,6 +58,12 @@ if __name__ == '__main__':
'-c', '--channel', default='stable',
help='Select update channel (default: %(default)s)')
parser.add_argument(
+ '-r', '--origin', default='local',
+ help='Select origin/repository (default: %(default)s)')
+ parser.add_argument(
+ '-s', '--suffix', default='',
+ help='Add an alphanumeric suffix to the package version, e.g. "dev"')
+ parser.add_argument(
'-o', '--output', default='yt_dlp/version.py',
help='The output file to write to (default: %(default)s)')
parser.add_argument(
@@ -66,6 +76,7 @@ if __name__ == '__main__':
args.version if args.version and '.' in args.version
else get_new_version(None, args.version))
write_file(args.output, VERSION_TEMPLATE.format(
- version=version, git_head=git_head, channel=args.channel))
+ version=version, git_head=git_head, channel=args.channel, origin=args.origin,
+ package_version=f'{version}{args.suffix}'))
print(f'version={version} ({args.channel}), head={git_head}')
diff --git a/devscripts/utils.py b/devscripts/utils.py
index f75a84da9..a952c9fae 100644
--- a/devscripts/utils.py
+++ b/devscripts/utils.py
@@ -13,10 +13,11 @@ def write_file(fname, content, mode='w'):
return f.write(content)
-def read_version(fname='yt_dlp/version.py'):
+def read_version(fname='yt_dlp/version.py', varname='__version__'):
"""Get the version without importing the package"""
- exec(compile(read_file(fname), fname, 'exec'))
- return locals()['__version__']
+ items = {}
+ exec(compile(read_file(fname), fname, 'exec'), items)
+ return items[varname]
def get_filename_args(has_infile=False, default_outfile=None):
diff --git a/setup.py b/setup.py
index 1740db27d..44055b0e9 100644
--- a/setup.py
+++ b/setup.py
@@ -18,7 +18,7 @@ except ImportError:
from devscripts.utils import read_file, read_version
-VERSION = read_version()
+VERSION = read_version(varname='_pkg_version')
DESCRIPTION = 'A youtube-dl fork with additional features and patches'
@@ -142,7 +142,7 @@ def main():
params = build_params()
setup(
- name='yt-dlp',
+ name='yt-dlp', # package name (do not change/remove comment)
version=VERSION,
maintainer='pukkandan',
maintainer_email='pukkandan.ytdlp@gmail.com',
diff --git a/yt_dlp/update.py b/yt_dlp/update.py
index db79df127..bdaa0d9be 100644
--- a/yt_dlp/update.py
+++ b/yt_dlp/update.py
@@ -28,6 +28,7 @@ from .version import CHANNEL, UPDATE_HINT, VARIANT, __version__
UPDATE_SOURCES = {
'stable': 'yt-dlp/yt-dlp',
'nightly': 'yt-dlp/yt-dlp-nightly-builds',
+ 'master': 'yt-dlp/yt-dlp-master-builds',
}
REPOSITORY = UPDATE_SOURCES['stable']
diff --git a/yt_dlp/version.py b/yt_dlp/version.py
index 9d0096316..a4b4d4101 100644
--- a/yt_dlp/version.py
+++ b/yt_dlp/version.py
@@ -9,3 +9,7 @@ VARIANT = None
UPDATE_HINT = None
CHANNEL = 'stable'
+
+ORIGIN = 'yt-dlp/yt-dlp'
+
+_pkg_version = '2023.10.13'