Automated release workflow (#1580)

This commit is contained in:
Srikanth Chekuri
2023-01-19 01:47:34 +05:30
committed by GitHub
parent e23dd5c25a
commit dd7afe0cc6
13 changed files with 728 additions and 117 deletions

6
.github/scripts/update-version.sh vendored Executable file
View 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

View 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
View 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

View File

@ -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

View 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

View 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

View File

@ -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
View 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
View 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

View File

@ -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 youre 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

View File

@ -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

View File

@ -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
View 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()