mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 04:34:01 +08:00
Automated release workflow (#1580)
This commit is contained in:
6
.github/scripts/update-version.sh
vendored
Executable file
6
.github/scripts/update-version.sh
vendored
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
sed -i "/\[stable\]/{n;s/version=.*/version=$1/}" eachdist.ini
|
||||
sed -i "/\[prerelease\]/{n;s/version=.*/version=$2/}" eachdist.ini
|
||||
|
||||
./scripts/eachdist.py update_versions --versions stable,prerelease
|
4
.github/scripts/use-cla-approved-github-bot.sh
vendored
Executable file
4
.github/scripts/use-cla-approved-github-bot.sh
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
git config user.name opentelemetrybot
|
||||
git config user.email 107717825+opentelemetrybot@users.noreply.github.com
|
43
.github/workflows/backport.yml
vendored
Normal file
43
.github/workflows/backport.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: Backport
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
number:
|
||||
description: "The pull request # to backport"
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x-0\.[0-9]+bx$ ]]; then
|
||||
echo this workflow should only be run against long-term release branches
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# history is needed to run git cherry-pick below
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use CLA approved github bot
|
||||
run: .github/scripts/use-cla-approved-github-bot.sh
|
||||
|
||||
- name: Create pull request
|
||||
env:
|
||||
NUMBER: ${{ github.event.inputs.number }}
|
||||
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
run: |
|
||||
commit=$(gh pr view $NUMBER --json mergeCommit --jq .mergeCommit.oid)
|
||||
title=$(gh pr view $NUMBER --json title --jq .title)
|
||||
|
||||
branch="opentelemetrybot/backport-${NUMBER}-to-${GITHUB_REF_NAME//\//-}"
|
||||
|
||||
git cherry-pick $commit
|
||||
git push origin HEAD:$branch
|
||||
gh pr create --title "[$GITHUB_REF_NAME] $title" \
|
||||
--body "Clean cherry-pick of #$NUMBER to the \`$GITHUB_REF_NAME\` branch." \
|
||||
--head $branch \
|
||||
--base $GITHUB_REF_NAME
|
4
.github/workflows/changelog.yml
vendored
4
.github/workflows/changelog.yml
vendored
@ -13,7 +13,9 @@ on:
|
||||
jobs:
|
||||
changelog:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'Skip Changelog')"
|
||||
if: |
|
||||
!contains(github.event.pull_request.labels.*.name, 'Skip Changelog')
|
||||
&& github.actor != 'opentelemetrybot'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
82
.github/workflows/prepare-patch-release.yml
vendored
Normal file
82
.github/workflows/prepare-patch-release.yml
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
name: Prepare patch release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
prepare-patch-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- run: |
|
||||
if [[ ! $GITHUB_REF_NAME =~ ^release/v[0-9]+\.[0-9]+\.x-0\.[0-9]+bx$ ]]; then
|
||||
echo this workflow should only be run against long-term release branches
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep --quiet "^## Unreleased$" CHANGELOG.md; then
|
||||
echo the change log is missing an \"Unreleased\" section
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Set environment variables
|
||||
run: |
|
||||
stable_version=$(./scripts/eachdist.py version --mode stable)
|
||||
unstable_version=$(./scripts/eachdist.py version --mode prerelease)
|
||||
|
||||
if [[ $stable_version =~ ^([0-9]+\.[0-9]+)\.([0-9]+)$ ]]; then
|
||||
stable_major_minor="${BASH_REMATCH[1]}"
|
||||
stable_patch="${BASH_REMATCH[2]}"
|
||||
else
|
||||
echo "unexpected stable_version: $stable_version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $unstable_version =~ ^0\.([0-9]+)b([0-9]+)$ ]]; then
|
||||
unstable_minor="${BASH_REMATCH[1]}"
|
||||
unstable_patch="${BASH_REMATCH[2]}"
|
||||
else
|
||||
echo "unexpected unstable_version: $unstable_version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
stable_version="$stable_major_minor.$((stable_patch + 1))"
|
||||
unstable_version="0.${unstable_minor}b$((unstable_patch + 1))"
|
||||
|
||||
echo "STABLE_VERSION=$stable_version" >> $GITHUB_ENV
|
||||
echo "UNSTABLE_VERSION=$unstable_version" >> $GITHUB_ENV
|
||||
|
||||
- name: Update version
|
||||
run: .github/scripts/update-version.sh $STABLE_VERSION $UNSTABLE_VERSION
|
||||
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
- name: Install tox
|
||||
run: pip install tox==3.27.1
|
||||
- name: run tox
|
||||
run: tox -e generate
|
||||
|
||||
- name: Update the change log with the approximate release date
|
||||
run: |
|
||||
date=$(date "+%Y-%m-%d")
|
||||
sed -Ei "s/^## Unreleased$/## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} ($date)/" CHANGELOG.md
|
||||
|
||||
- name: Use CLA approved github bot
|
||||
run: .github/scripts/use-cla-approved-github-bot.sh
|
||||
|
||||
- name: Create pull request
|
||||
env:
|
||||
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
run: |
|
||||
message="Prepare release ${STABLE_VERSION}/${UNSTABLE_VERSION}"
|
||||
branch="opentelemetrybot/prepare-release-${STABLE_VERSION}-${UNSTABLE_VERSION}"
|
||||
|
||||
git commit -a -m "$message"
|
||||
git push origin HEAD:$branch
|
||||
gh pr create --title "[$GITHUB_REF_NAME] $message" \
|
||||
--body "$message." \
|
||||
--head $branch \
|
||||
--base $GITHUB_REF_NAME
|
195
.github/workflows/prepare-release-branch.yml
vendored
Normal file
195
.github/workflows/prepare-release-branch.yml
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
name: Prepare release branch
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
prerelease_version:
|
||||
description: "Pre-release version number? (e.g. 1.9.0rc2)"
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
prereqs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Verify prerequisites
|
||||
env:
|
||||
PRERELEASE_VERSION: ${{ github.event.inputs.prerelease_version }}
|
||||
run: |
|
||||
if [[ $GITHUB_REF_NAME != main ]]; then
|
||||
echo this workflow should only be run against main
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep --quiet "^## Unreleased$" CHANGELOG.md; then
|
||||
echo the change log is missing an \"Unreleased\" section
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -z $PRERELEASE_VERSION ]]; then
|
||||
stable_version=$(./scripts/eachdist.py version --mode stable)
|
||||
stable_version=${stable_version//.dev/}
|
||||
if [[ $PRERELEASE_VERSION != ${stable_version}* ]]; then
|
||||
echo "$PRERELEASE_VERSION is not a prerelease for the version on main ($stable_version)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
create-pull-request-against-release-branch:
|
||||
runs-on: ubuntu-latest
|
||||
needs: prereqs
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Create release branch
|
||||
env:
|
||||
PRERELEASE_VERSION: ${{ github.event.inputs.prerelease_version }}
|
||||
run: |
|
||||
if [[ -z $PRERELEASE_VERSION ]]; then
|
||||
stable_version=$(./scripts/eachdist.py version --mode stable)
|
||||
stable_version=${stable_version//.dev/}
|
||||
else
|
||||
stable_version=$PRERELEASE_VERSION
|
||||
fi
|
||||
|
||||
unstable_version=$(./scripts/eachdist.py version --mode prerelease)
|
||||
unstable_version=${unstable_version//.dev/}
|
||||
|
||||
if [[ $stable_version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then
|
||||
stable_version_branch_part=$(echo $stable_version | sed -E 's/([0-9]+)\.([0-9]+)\.0/\1.\2.x/')
|
||||
unstable_version_branch_part=$(echo $unstable_version | sed -E 's/0\.([0-9]+)b0/0.\1bx/')
|
||||
release_branch_name="release/v${stable_version_branch_part}-${unstable_version_branch_part}"
|
||||
elif [[ $stable_version =~ ^([0-9]+)\.([0-9]+)\.0 ]]; then
|
||||
# pre-release version, e.g. 1.9.0rc2
|
||||
release_branch_name="release/v$stable_version-$unstable_version"
|
||||
else
|
||||
echo "unexpected version: $stable_version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git push origin HEAD:$release_branch_name
|
||||
|
||||
echo "STABLE_VERSION=$stable_version" >> $GITHUB_ENV
|
||||
echo "UNSTABLE_VERSION=$unstable_version" >> $GITHUB_ENV
|
||||
echo "RELEASE_BRANCH_NAME=$release_branch_name" >> $GITHUB_ENV
|
||||
|
||||
- name: Update version
|
||||
run: .github/scripts/update-version.sh $STABLE_VERSION $UNSTABLE_VERSION
|
||||
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
- name: Install tox
|
||||
run: pip install tox==3.27.1
|
||||
- name: run tox
|
||||
run: tox -e generate
|
||||
|
||||
- name: Update the change log with the approximate release date
|
||||
run: |
|
||||
date=$(date "+%Y-%m-%d")
|
||||
sed -Ei "s/^## Unreleased$/## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} ($date)/" CHANGELOG.md
|
||||
|
||||
- name: Use CLA approved github bot
|
||||
run: .github/scripts/use-cla-approved-github-bot.sh
|
||||
|
||||
- name: Create pull request against the release branch
|
||||
env:
|
||||
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
run: |
|
||||
message="Prepare release ${STABLE_VERSION}/${UNSTABLE_VERSION}"
|
||||
branch="opentelemetrybot/prepare-release-${STABLE_VERSION}-${UNSTABLE_VERSION}"
|
||||
|
||||
git commit -a -m "$message"
|
||||
git push origin HEAD:$branch
|
||||
gh pr create --title "[$RELEASE_BRANCH_NAME] $message" \
|
||||
--body "$message." \
|
||||
--head $branch \
|
||||
--base $RELEASE_BRANCH_NAME
|
||||
|
||||
create-pull-request-against-main:
|
||||
runs-on: ubuntu-latest
|
||||
needs: prereqs
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set environment variables
|
||||
env:
|
||||
PRERELEASE_VERSION: ${{ github.event.inputs.prerelease_version }}
|
||||
run: |
|
||||
if [[ -z $PRERELEASE_VERSION ]]; then
|
||||
stable_version=$(./scripts/eachdist.py version --mode stable)
|
||||
stable_version=${stable_version//.dev/}
|
||||
else
|
||||
stable_version=$PRERELEASE_VERSION
|
||||
fi
|
||||
|
||||
unstable_version=$(./scripts/eachdist.py version --mode prerelease)
|
||||
unstable_version=${unstable_version//.dev/}
|
||||
|
||||
if [[ $stable_version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then
|
||||
stable_major="${BASH_REMATCH[1]}"
|
||||
stable_minor="${BASH_REMATCH[2]}"
|
||||
stable_next_version="$stable_major.$((stable_minor + 1)).0"
|
||||
elif [[ $stable_version =~ ^([0-9]+)\.([0-9]+)\.0 ]]; then
|
||||
# pre-release version, e.g. 1.9.0rc2
|
||||
stable_major="${BASH_REMATCH[1]}"
|
||||
stable_minor="${BASH_REMATCH[2]}"
|
||||
stable_next_version="$stable_major.$stable_minor.0"
|
||||
else
|
||||
echo "unexpected stable_version: $stable_version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $unstable_version =~ ^0\.([0-9]+)b[0-9]+$ ]]; then
|
||||
unstable_minor="${BASH_REMATCH[1]}"
|
||||
else
|
||||
echo "unexpected unstable_version: $unstable_version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
unstable_next_version="0.$((unstable_minor + 1))b0"
|
||||
|
||||
echo "STABLE_VERSION=${stable_version}" >> $GITHUB_ENV
|
||||
echo "STABLE_NEXT_VERSION=${stable_next_version}.dev" >> $GITHUB_ENV
|
||||
|
||||
echo "UNSTABLE_VERSION=${unstable_version}" >> $GITHUB_ENV
|
||||
echo "UNSTABLE_NEXT_VERSION=${unstable_next_version}.dev" >> $GITHUB_ENV
|
||||
|
||||
- name: Update version
|
||||
run: .github/scripts/update-version.sh $STABLE_NEXT_VERSION $UNSTABLE_NEXT_VERSION
|
||||
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
- name: Install tox
|
||||
run: pip install tox==3.27.1
|
||||
- name: run tox
|
||||
run: tox -e generate
|
||||
|
||||
- name: Update the change log on main
|
||||
run: |
|
||||
# the actual release date on main will be updated at the end of the release workflow
|
||||
date=$(date "+%Y-%m-%d")
|
||||
sed -Ei "s/^## Unreleased$/## Unreleased\n\n## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} ($date)/" CHANGELOG.md
|
||||
|
||||
- name: Use CLA approved github bot
|
||||
run: .github/scripts/use-cla-approved-github-bot.sh
|
||||
|
||||
- name: Create pull request against main
|
||||
env:
|
||||
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
run: |
|
||||
message="Update version to ${STABLE_NEXT_VERSION}/${UNSTABLE_NEXT_VERSION}"
|
||||
body="Update version to \`${STABLE_NEXT_VERSION}/${UNSTABLE_NEXT_VERSION}\`."
|
||||
branch="opentelemetrybot/update-version-to-${STABLE_NEXT_VERSION}-${UNSTABLE_NEXT_VERSION}"
|
||||
|
||||
git commit -a -m "$message"
|
||||
git push origin HEAD:$branch
|
||||
gh pr create --title "$message" \
|
||||
--body "$body" \
|
||||
--head $branch \
|
||||
--base main
|
37
.github/workflows/publish.yml
vendored
37
.github/workflows/publish.yml
vendored
@ -1,37 +0,0 @@
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- name: Build wheels
|
||||
run: ./scripts/build.sh
|
||||
- name: Install twine
|
||||
run: |
|
||||
pip install twine
|
||||
# The step below publishes to testpypi in order to catch any issues
|
||||
# with the package configuration that would cause a failure to upload
|
||||
# to pypi. One example of such a failure is if a classifier is
|
||||
# rejected by pypi (e.g "3 - Beta"). This would cause a failure during the
|
||||
# middle of the package upload causing the action to fail, and certain packages
|
||||
# might have already been updated, this would be bad.
|
||||
- name: Publish to TestPyPI
|
||||
env:
|
||||
TWINE_USERNAME: '__token__'
|
||||
TWINE_PASSWORD: ${{ secrets.test_pypi_token }}
|
||||
run: |
|
||||
twine upload --repository testpypi --skip-existing --verbose dist/*
|
||||
- name: Publish to PyPI
|
||||
env:
|
||||
TWINE_USERNAME: '__token__'
|
||||
TWINE_PASSWORD: ${{ secrets.pypi_password }}
|
||||
run: |
|
||||
twine upload --skip-existing --verbose dist/*
|
205
.github/workflows/release.yml
vendored
Normal file
205
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
name: Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
if [[ $GITHUB_REF_NAME != release/* ]]; then
|
||||
echo this workflow should only be run against release branches
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set environment variables
|
||||
run: |
|
||||
stable_version=$(./scripts/eachdist.py version --mode stable)
|
||||
unstable_version=$(./scripts/eachdist.py version --mode prerelease)
|
||||
|
||||
if [[ $stable_version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
|
||||
stable_major="${BASH_REMATCH[1]}"
|
||||
stable_minor="${BASH_REMATCH[2]}"
|
||||
stable_patch="${BASH_REMATCH[3]}"
|
||||
else
|
||||
echo "unexpected stable_version: $stable_version"
|
||||
exit 1
|
||||
fi
|
||||
if [[ $stable_patch != 0 ]]; then
|
||||
if [[ $unstable_version =~ ^0\.([0-9]+)b([0-9]+)$ ]]; then
|
||||
unstable_minor="${BASH_REMATCH[1]}"
|
||||
unstable_patch="${BASH_REMATCH[2]}"
|
||||
else
|
||||
echo "unexpected unstable_version: $unstable_version"
|
||||
exit 1
|
||||
fi
|
||||
if [[ $unstable_patch != 0 ]]; then
|
||||
prior_version_when_patch="$stable_major.$stable_minor.$((stable_patch - 1))/0.${unstable_minor}b$((unstable_patch - 1))"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "STABLE_VERSION=$stable_version" >> $GITHUB_ENV
|
||||
echo "UNSTABLE_VERSION=$unstable_version" >> $GITHUB_ENV
|
||||
|
||||
echo "PRIOR_VERSION_WHEN_PATCH=$prior_version_when_patch" >> $GITHUB_ENV
|
||||
|
||||
# check out main branch to verify there won't be problems with merging the change log
|
||||
# at the end of this workflow
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: main
|
||||
|
||||
- run: |
|
||||
if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then
|
||||
# not making a patch release
|
||||
if ! grep --quiet "^## Version ${STABLE_VERSION}/${UNSTABLE_VERSION} " CHANGELOG.md; then
|
||||
echo the pull request generated by prepare-release-branch.yml needs to be merged first
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# back to the release branch
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# next few steps publish to pypi
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.7'
|
||||
|
||||
- name: Build wheels
|
||||
run: ./scripts/build.sh
|
||||
|
||||
- name: Install twine
|
||||
run: |
|
||||
pip install twine
|
||||
|
||||
# The step below publishes to testpypi in order to catch any issues
|
||||
# with the package configuration that would cause a failure to upload
|
||||
# to pypi. One example of such a failure is if a classifier is
|
||||
# rejected by pypi (e.g "3 - Beta"). This would cause a failure during the
|
||||
# middle of the package upload causing the action to fail, and certain packages
|
||||
# might have already been updated, this would be bad.
|
||||
- name: Publish to TestPyPI
|
||||
env:
|
||||
TWINE_USERNAME: '__token__'
|
||||
TWINE_PASSWORD: ${{ secrets.test_pypi_token }}
|
||||
run: |
|
||||
twine upload --repository testpypi --skip-existing --verbose dist/*
|
||||
|
||||
- name: Publish to PyPI
|
||||
env:
|
||||
TWINE_USERNAME: '__token__'
|
||||
TWINE_PASSWORD: ${{ secrets.pypi_password }}
|
||||
run: |
|
||||
twine upload --skip-existing --verbose dist/*
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
# conditional block not indented because of the heredoc
|
||||
if [[ ! -z $PRIOR_VERSION_WHEN_PATCH ]]; then
|
||||
cat > /tmp/release-notes.txt << EOF
|
||||
This is a patch release on the previous $PRIOR_VERSION_WHEN_PATCH release, fixing the issue(s) below.
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
# CHANGELOG_SECTION.md is also used at the end of the release workflow
|
||||
# for copying the change log updates to main
|
||||
sed -n "0,/^## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} /d;/^## Version /q;p" CHANGELOG.md \
|
||||
> /tmp/CHANGELOG_SECTION.md
|
||||
|
||||
# the complex perl regex is needed because markdown docs render newlines as soft wraps
|
||||
# while release notes render them as line breaks
|
||||
perl -0pe 's/(?<!\n)\n *(?!\n)(?![-*] )(?![1-9]+\. )/ /g' /tmp/CHANGELOG_SECTION.md \
|
||||
>> /tmp/release-notes.txt
|
||||
|
||||
- name: Create GitHub release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh release create --target $GITHUB_REF_NAME \
|
||||
--title "Version ${STABLE_VERSION}/${UNSTABLE_VERSION}" \
|
||||
--notes-file /tmp/release-notes.txt \
|
||||
--discussion-category announcements \
|
||||
v$STABLE_VERSION
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# the step below is creating a pull request against main
|
||||
ref: main
|
||||
|
||||
- name: Copy change log updates to main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then
|
||||
# this was not a patch release, so the version exists already in the CHANGELOG.md
|
||||
|
||||
# update the release date
|
||||
date=$(gh release view v$STABLE_VERSION --json publishedAt --jq .publishedAt | sed 's/T.*//')
|
||||
sed -Ei "s/## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} .*/## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} ($date)/" CHANGELOG.md
|
||||
|
||||
# the entries are copied over from the release branch to support workflows
|
||||
# where change log entries may be updated after preparing the release branch
|
||||
|
||||
# copy the portion above the release, up to and including the heading
|
||||
sed -n "0,/^## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} ($date)/p" CHANGELOG.md > /tmp/CHANGELOG.md
|
||||
|
||||
# copy the release notes
|
||||
cat /tmp/CHANGELOG_SECTION.md >> /tmp/CHANGELOG.md
|
||||
|
||||
# copy the portion below the release
|
||||
sed -n "0,/^## Version ${STABLE_VERSION}\/${UNSTABLE_VERSION} /d;0,/^## Version /{/^## Version/!d};p" CHANGELOG.md \
|
||||
>> /tmp/CHANGELOG.md
|
||||
|
||||
# update the real CHANGELOG.md
|
||||
cp /tmp/CHANGELOG.md CHANGELOG.md
|
||||
else
|
||||
# this was a patch release, so the version does not exist already in the CHANGELOG.md
|
||||
|
||||
# copy the portion above the top-most release, not including the heading
|
||||
sed -n "0,/^## Version /{ /^## Version /!p }" CHANGELOG.md > /tmp/CHANGELOG.md
|
||||
|
||||
# add the heading
|
||||
date=$(gh release view v$STABLE_VERSION --json publishedAt --jq .publishedAt | sed 's/T.*//')
|
||||
echo "## Version ${STABLE_VERSION}/${UNSTABLE_VERSION} ($date)" >> /tmp/CHANGELOG.md
|
||||
|
||||
# copy the release notes
|
||||
cat /tmp/CHANGELOG_SECTION.md >> /tmp/CHANGELOG.md
|
||||
|
||||
# copy the portion starting from the top-most release
|
||||
sed -n "/^## Version /,\$p" CHANGELOG.md >> /tmp/CHANGELOG.md
|
||||
|
||||
# update the real CHANGELOG.md
|
||||
cp /tmp/CHANGELOG.md CHANGELOG.md
|
||||
fi
|
||||
|
||||
- name: Use CLA approved github bot
|
||||
run: .github/scripts/use-cla-approved-github-bot.sh
|
||||
|
||||
- name: Create pull request against main
|
||||
env:
|
||||
# not using secrets.GITHUB_TOKEN since pull requests from that token do not run workflows
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
run: |
|
||||
message="Copy change log updates from $GITHUB_REF_NAME"
|
||||
body="Copy log updates from \`$GITHUB_REF_NAME\`."
|
||||
branch="opentelemetrybot/copy-change-log-updates-from-${GITHUB_REF_NAME//\//-}"
|
||||
|
||||
if [[ -z $PRIOR_VERSION_WHEN_PATCH ]]; then
|
||||
if git diff --quiet; then
|
||||
echo there are no updates needed to the change log on main, not creating pull request
|
||||
exit 0 # success
|
||||
fi
|
||||
fi
|
||||
|
||||
git commit -a -m "$message"
|
||||
git push origin HEAD:$branch
|
||||
gh pr create --title "$message" \
|
||||
--body "$body" \
|
||||
--head $branch \
|
||||
--base main
|
50
.github/workflows/update-sha.yml
vendored
Normal file
50
.github/workflows/update-sha.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: Update SHA
|
||||
|
||||
on: issue_comment
|
||||
|
||||
jobs:
|
||||
update-pr-sha:
|
||||
name: Update SHA
|
||||
if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, 'update-sha') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
# would have been lit if github supported string split expression
|
||||
- name: Extract branch name from comment to get commit SHA
|
||||
uses: jungwinter/split@v2
|
||||
id: split
|
||||
with:
|
||||
msg: ${{ github.event.comment.body }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Use CLA approved github bot
|
||||
run: .github/scripts/use-cla-approved-github-bot.sh
|
||||
|
||||
- name: Checkout Pull Request
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
run: |
|
||||
PR_URL="${{ github.event.issue.pull_request.url }}"
|
||||
PR_NUM=${PR_URL##*/}
|
||||
echo "Checking out from PR #$PR_NUM based on URL: $PR_URL"
|
||||
hub pr checkout $PR_NUM
|
||||
|
||||
# caching is not supported for this event type
|
||||
- name: Run script
|
||||
run: |
|
||||
python -m pip install requests==2.28.1 ruamel.yaml==0.17.21
|
||||
python scripts/update_sha.py --branch ${{ steps.split.outputs._1 }}
|
||||
|
||||
- name: Commit and Push changes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
run: |
|
||||
git commit -a -m "Update SHA"
|
||||
git push
|
141
RELEASING.md
141
RELEASING.md
@ -1,93 +1,90 @@
|
||||
# Releasing OpenTelemetry Packages (for maintainers only)
|
||||
This document explains how to publish all OT modules at version x.y.z. Ensure that you’re following semver when choosing a version number.
|
||||
# Release instructions
|
||||
|
||||
Release Process:
|
||||
* [Checkout a clean repo](#checkout-a-clean-repo)
|
||||
* [Update versions](#update-versions)
|
||||
* [Create a new branch](#create-a-new-branch)
|
||||
* [Open a Pull Request](#open-a-pull-request)
|
||||
* [Create a Release](#Create-a-Release)
|
||||
* [Move stable tag](#Move-stable-tag)
|
||||
* [Update main](#Update-main)
|
||||
* [Check PyPI](#Check-PyPI)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
## Preparing a new major or minor release
|
||||
|
||||
## Checkout a clean repo
|
||||
To avoid pushing untracked changes, check out the repo in a new dir
|
||||
* Run the [Prepare release branch workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/prepare-release-branch.yml).
|
||||
* Press the "Run workflow" button, and leave the default branch `main` selected.
|
||||
* If making a pre-release of stable components (e.g. release candidate),
|
||||
enter the pre-release version number, e.g. `1.9.0rc2`.
|
||||
(otherwise the workflow will pick up the version from `main` and just remove the `.dev` suffix).
|
||||
* Review and merge the two pull requests that it creates
|
||||
(one is targeted to the release branch and one is targeted to `main`).
|
||||
|
||||
## Update versions
|
||||
The update of the version information relies on the information in eachdist.ini to identify which packages are stable, prerelease or
|
||||
experimental. Update the desired version there to begin the release process.
|
||||
## Preparing a new patch release
|
||||
|
||||
## Create a new branch
|
||||
The following script does the following:
|
||||
- update main locally
|
||||
- creates a new release branch `release/<version>`
|
||||
- updates version and changelog files
|
||||
- commits the change
|
||||
* Backport pull request(s) to the release branch.
|
||||
* Run the [Backport workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/backport.yml).
|
||||
* Press the "Run workflow" button, then select the release branch from the dropdown list,
|
||||
e.g. `release/v1.9.x`, then enter the pull request number that you want to backport,
|
||||
then click the "Run workflow" button below that.
|
||||
* Review and merge the backport pull request that it generates.
|
||||
* Merge a pull request to the release branch updating the `CHANGELOG.md`.
|
||||
* The heading for the unreleased entries should be `## Unreleased`.
|
||||
* Run the [Prepare patch release workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/prepare-patch-release.yml).
|
||||
* Press the "Run workflow" button, then select the release branch from the dropdown list,
|
||||
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
|
||||
* Review and merge the pull request that it creates for updating the version.
|
||||
|
||||
*NOTE: This script was run by a GitHub Action but required the Action bot to be excluded from the CLA check, which it currently is not.*
|
||||
## Making the release
|
||||
|
||||
```bash
|
||||
./scripts/prepare_release.sh
|
||||
```
|
||||
* Run the [Release workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/release.yml).
|
||||
* Press the "Run workflow" button, then select the release branch from the dropdown list,
|
||||
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
|
||||
* This workflow will publish the artifacts and publish a GitHub release with release notes based on the change log.
|
||||
* Review and merge the pull request that it creates for updating the change log in main
|
||||
(note that if this is not a patch release then the change log on main may already be up-to-date,
|
||||
in which case no pull request will be created).
|
||||
|
||||
## Open a Pull Request
|
||||
## Notes about version numbering for stable components
|
||||
|
||||
The PR should be opened from the `release/<version>` branch created as part of running `prepare_release.sh` in the steps above.
|
||||
* The version number for stable components in the `main` branch is always `X.Y.0.dev`,
|
||||
where `X.Y.0` represents the next minor release.
|
||||
* When the release branch is created, you can opt to make a "pre-release", e.g. `X.Y.0rc2`.
|
||||
* If you ARE NOT making a "pre-release":
|
||||
* A "long-term" release branch will be created, e.g. `release/v1.9.x-0.21bx` (notice the wildcard x's).
|
||||
Later on, after the initial release, you can backport PRs to a "long-term" release branch and make patch releases
|
||||
from it.
|
||||
* The version number for stable components in the release branch will be bumped to remove the `.dev`,
|
||||
e.g. `X.Y.0`.
|
||||
* The version number for stable components in the `main` branch will be bumped to the next version,
|
||||
e.g. `X.{Y+1}.0.dev`.
|
||||
* If you ARE making a "pre-release":
|
||||
* A "short-term" release branch will be created, e.g. `release/v1.9.0rc2-0.21b0` (notice the precise version with no
|
||||
wildcard x's). "Short-term" release branches do not support backports or patch releases after the initial release.
|
||||
* The version number for stable components in the `main` branch will not be bumped, e.g. it will remain `X.Y.0.dev`
|
||||
since the next minor release will still be `X.Y.0`.
|
||||
|
||||
## Create a Release
|
||||
## Notes about version numbering for unstable components
|
||||
|
||||
- Create the GH release from the main branch, using a new tag for this micro version, e.g. `v0.7.0`
|
||||
- Copy the changelogs from all packages that changed into the release notes (and reformat to remove hard line wraps)
|
||||
* The version number for unstable components in the `main` branch is always `0.Yb0.dev`,
|
||||
where `0.Yb0` represents the next minor release.
|
||||
* _Question: Is "b" (beta) redundant on "0." releases, or is this a python thing? I'm wondering if we can change it to `0.Y.0` to match up with the practice in js and go repos._
|
||||
* Unstable components do not need "pre-releases", and so whether or not you are making a "pre-release" of stable
|
||||
components:
|
||||
* The version number for unstable components in the release branch will be bumped to remove the `.dev`,
|
||||
e.g. `0.Yb0`.
|
||||
* The version number for unstable components in the `main` branch will be bumped to the next version,
|
||||
e.g. `0.{Y+1}b0.dev`.
|
||||
|
||||
## After the release
|
||||
|
||||
## Check PyPI
|
||||
|
||||
This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python/blob/main/.github/workflows/publish.yml).
|
||||
|
||||
- Check the [action logs](https://github.com/open-telemetry/opentelemetry-python/actions?query=workflow%3APublish) to make sure packages have been uploaded to PyPI
|
||||
- Check the release history (e.g. https://pypi.org/project/opentelemetry-api/#history) on PyPI
|
||||
|
||||
If for some reason the action failed, see [Publish failed](#publish-failed) below
|
||||
|
||||
## Move stable tag
|
||||
|
||||
This will ensure the docs are pointing at the stable release.
|
||||
|
||||
* Check PyPI
|
||||
* This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python/blob/main/.github/workflows/publish.yml).
|
||||
* Check the [action logs](https://github.com/open-telemetry/opentelemetry-python/actions?query=workflow%3APublish) to make sure packages have been uploaded to PyPI
|
||||
* Check the release history (e.g. https://pypi.org/project/opentelemetry-api/#history) on PyPI
|
||||
* If for some reason the action failed, see [Publish failed](#publish-failed) below
|
||||
* Move stable tag
|
||||
* Run the following (TODO automate):
|
||||
```bash
|
||||
git tag -d stable
|
||||
git tag stable
|
||||
git push --delete origin tagname
|
||||
git push origin stable
|
||||
```
|
||||
|
||||
To validate this worked, ensure the stable build has run successfully: https://readthedocs.org/projects/opentelemetry-python/builds/. If the build has not run automatically, it can be manually trigger via the readthedocs interface.
|
||||
|
||||
## Update main
|
||||
|
||||
Ensure the version and changelog updates have been applied to main. Update the versions in eachdist.ini once again this time to include the `.dev0` tag and
|
||||
run eachdist once again:
|
||||
```bash
|
||||
./scripts/eachdist.py update_versions --versions stable,prerelease
|
||||
```
|
||||
|
||||
If the diff includes significant changes, create a pull request to commit the changes and once the changes are merged, click the "Run workflow" button for the Update [OpenTelemetry Website Docs](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/docs-update.yml) GitHub Action.
|
||||
|
||||
## Hotfix procedure
|
||||
|
||||
A `hotfix` is defined as a small change developed to correct a bug that should be released as quickly as possible. Due to the nature of hotfixes, they usually will only affect one or a few packages. Therefore, it usually is not necessary to go through the entire release process outlined above for hotfixes. Follow the below steps how to release a hotfix:
|
||||
|
||||
1. Identify the packages that are affected by the bug. Make the changes to those packages, merging to `main`, as quickly as possible.
|
||||
2. On your local machine, remove the `dev0` tags from the version number and increment the patch version number.
|
||||
3. On your local machine, update `CHANGELOG.md` with the date of the hotfix change.
|
||||
4. With administrator privileges for PyPi, manually publish the affected packages.
|
||||
a. Install [twine](https://pypi.org/project/twine/)
|
||||
b. Navigate to where the `setup.py` file exists for the package you want to publish.
|
||||
c. Run `python setup.py sdist bdist_wheel`. You may have to install [wheel](https://pypi.org/project/wheel/) as well.
|
||||
d. Validate your built distributions by running `twine check dist/*`.
|
||||
e. Upload distributions to PyPi by running `twine upload dist/*`.
|
||||
5. Note that since hotfixes are manually published, the build scripts for publish after creating a release are not run.
|
||||
* This will ensure the docs are pointing at the stable release.
|
||||
* To validate this worked, ensure the stable build has run successfully:
|
||||
https://readthedocs.org/projects/opentelemetry-python/builds/.
|
||||
If the build has not run automatically, it can be manually trigger via the readthedocs interface.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
@ -16,3 +16,5 @@ mypy-protobuf>=1.23
|
||||
protobuf~=3.13
|
||||
markupsafe==2.0.1
|
||||
codespell==2.1.0
|
||||
requests==2.28.1
|
||||
ruamel.yaml==0.17.21
|
||||
|
@ -71,7 +71,9 @@ def main():
|
||||
root_path, "opentelemetry-contrib-instrumentations", "pyproject.toml"
|
||||
)
|
||||
|
||||
deps = [f"{pkg}=={version}" for pkg, version in dependencies]
|
||||
deps = [
|
||||
f"{pkg.strip()}=={version.strip()}" for pkg, version in dependencies
|
||||
]
|
||||
with open(pyproject_toml_path, "rb") as file:
|
||||
pyproject_toml = tomli.load(file)
|
||||
|
||||
|
60
scripts/update_sha.py
Normal file
60
scripts/update_sha.py
Normal file
@ -0,0 +1,60 @@
|
||||
# Copyright The OpenTelemetry Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# pylint: disable=import-error,unspecified-encoding
|
||||
|
||||
import argparse
|
||||
|
||||
import requests
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
API_URL = (
|
||||
"https://api.github.com/repos/open-telemetry/opentelemetry-python/commits/"
|
||||
)
|
||||
WORKFLOW_FILE = ".github/workflows/test.yml"
|
||||
|
||||
|
||||
def get_sha(branch):
|
||||
url = API_URL + branch
|
||||
response = requests.get(url)
|
||||
response.raise_for_status()
|
||||
return response.json()["sha"]
|
||||
|
||||
|
||||
def update_sha(sha):
|
||||
yaml = YAML()
|
||||
yaml.preserve_quotes = True
|
||||
with open(WORKFLOW_FILE, "r") as file:
|
||||
workflow = yaml.load(file)
|
||||
workflow["env"]["CORE_REPO_SHA"] = sha
|
||||
with open(WORKFLOW_FILE, "w") as file:
|
||||
yaml.dump(workflow, file)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
sha = get_sha(args.branch)
|
||||
update_sha(sha)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Updates the SHA in the workflow file"
|
||||
)
|
||||
parser.add_argument("-b", "--branch", help="branch to use")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user