Skip to content

Commit

Permalink
Add publishing conventions and release workflow (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg authored Aug 30, 2023
1 parent 6738564 commit 1fe2538
Show file tree
Hide file tree
Showing 9 changed files with 432 additions and 2 deletions.
90 changes: 90 additions & 0 deletions .github/scripts/generate-release-contributors.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash -e

# shellcheck disable=SC2016
# shellcheck disable=SC2086

# this should be run on the release branch

# NOTE if you need to run this script locally, you will need to first:
# git fetch upstream main
# git push origin upstream/main:main
# export GITHUB_REPOSITORY=open-telemetry/semantic-conventions-java

from_version=$1

# get the date of the first commit that was not in the from_version
from=$(git log --reverse --pretty=format:"%cI" $from_version..HEAD | head -1)

# get the last commit on main that was included in the release
to=$(git merge-base origin/main HEAD | xargs git log -1 --pretty=format:"%cI")

contributors1=$(gh api graphql --paginate -F q="repo:$GITHUB_REPOSITORY is:pr base:main is:merged merged:$from..$to" -f query='
query($q: String!, $endCursor: String) {
search(query: $q, type: ISSUE, first: 100, after: $endCursor) {
edges {
node {
... on PullRequest {
author { login }
reviews(first: 100) {
nodes {
author { login }
}
}
comments(first: 100) {
nodes {
author { login }
}
}
closingIssuesReferences(first: 100) {
nodes {
author { login }
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}' --jq '.data.search.edges.[].node.author.login,
.data.search.edges.[].node.reviews.nodes.[].author.login,
.data.search.edges.[].node.comments.nodes.[].author.login,
.data.search.edges.[].node.closingIssuesReferences.nodes.[].author.login')

# this query captures authors of issues which have had PRs in the current range reference the issue
# but not necessarily through closingIssuesReferences (e.g. addressing just a part of an issue)
contributors2=$(gh api graphql --paginate -F q="repo:$GITHUB_REPOSITORY is:pr base:main is:merged merged:$from..$to" -f query='
query($q: String!, $endCursor: String) {
search(query: $q, type: ISSUE, first: 100, after: $endCursor) {
edges {
node {
... on PullRequest {
body
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
' --jq '.data.search.edges.[].node.body' \
| grep -oE "#[0-9]{4,}$|#[0-9]{4,}[^0-9<]|$GITHUB_REPOSITORY/issues/[0-9]{4,}" \
| grep -oE "[0-9]{4,}" \
| xargs -I{} gh issue view {} --json 'author,url' --jq '[.author.login,.url]' \
| grep -v '/pull/' \
| sed 's/^\["//' \
| sed 's/".*//')

echo $contributors1 $contributors2 \
| sed 's/ /\n/g' \
| sort -uf \
| grep -v linux-foundation-easycla \
| grep -v github-actions \
| grep -v dependabot \
| grep -v codecov \
| grep -v opentelemetrybot \
| sed 's/^/@/'
3 changes: 3 additions & 0 deletions .github/scripts/get-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash -e

grep -Eo "var semanticConventionsVersion = \".*\"" build.gradle.kts | grep -Eo "[0-9]+.[0-9]+.[0-9]+"
4 changes: 4 additions & 0 deletions .github/scripts/use-cla-approved-github-bot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash -e

git config user.name opentelemetrybot
git config user.email 107717825+opentelemetrybot@users.noreply.github.com
115 changes: 115 additions & 0 deletions .github/workflows/prepare-release-branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Prepare release branch
on:
workflow_dispatch:

jobs:
prereqs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Verify prerequisites
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
create-pull-request-against-release-branch:
runs-on: ubuntu-latest
needs:
- prereqs
steps:
- uses: actions/checkout@v3

- name: Create release branch
run: |
version=$(.github/scripts/get-version.sh)
if [[ $version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then
release_branch_name="release/v${version}"
git ls-remote --exit-code --heads origin refs/heads/$release_branch_name
if [ "$?" == "0" ] ; then
echo "release branch $release_branch_name already exists"
exit 1
fi
else
echo "unexpected version: $version"
exit 1
fi
git push origin HEAD:$release_branch_name
echo "VERSION=$version" >> $GITHUB_ENV
echo "RELEASE_BRANCH_NAME=$release_branch_name" >> $GITHUB_ENV
- name: Update version
run: sed -Ei "s/val snapshot = true/val snapshot = false/" build.gradle.kts

- name: Update the change log with the approximate release date
run: |
date=$(date "+%Y-%m-%d")
sed -Ei "s/^## Unreleased$/## Version $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
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
run: |
message="Prepare release $VERSION"
branch="opentelemetrybot/prepare-release-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"
git push --set-upstream origin $branch
gh pr create --title "[$RELEASE_BRANCH_NAME] $message" \
--body "$message." \
--base $RELEASE_BRANCH_NAME
create-pull-request-against-main:
runs-on: ubuntu-latest
needs:
- prereqs
steps:
- uses: actions/checkout@v3

- name: Set environment variables
run: |
version=$(.github/scripts/get-version.sh)
if [[ ! $version =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then
echo "unexpected version: $version"
exit 1
fi
echo "VERSION=$version" >> $GITHUB_ENV
- 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 $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
GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
run: |
message="Update changelog for $VERSION release"
body="Update changelog for \`$VERSION\` release."
branch="opentelemetrybot/update-version-to-${VERSION}"
git checkout -b $branch
git commit -a -m "$message"
git push --set-upstream origin $branch
gh pr create --title "$message" \
--body "$body" \
--base main
114 changes: 114 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Release
on:
workflow_dispatch:

jobs:
release:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.create-github-release.outputs.version }}
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

- uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17

- name: Build and publish artifacts
uses: gradle/gradle-build-action@v2
with:
# TODO(jack-berg): add following arguments when confident in release process: closeAndReleaseSonatypeStagingRepository
arguments: assemble publishToSonatype
env:
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
SONATYPE_KEY: ${{ secrets.SONATYPE_KEY }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }}

- name: Set environment variables
run: |
version=$(.github/scripts/get-version.sh)
if [[ $version =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
patch="${BASH_REMATCH[3]}"
else
echo "unexpected version: $version"
exit 1
fi
if [[ $patch == 0 ]]; then
if [[ $minor == 0 ]]; then
prior_major=$((major - 1))
prior_minor=$(grep -Po "^## Version $prior_major.\K[0-9]+" CHANGELOG.md | head -1)
prior_version="$prior_major.$prior_minor"
else
prior_version="$major.$((minor - 1)).0"
fi
else
prior_version="$major.$minor.$((patch - 1))"
fi
echo "VERSION=$version" >> $GITHUB_ENV
echo "PRIOR_VERSION=$prior_version" >> $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

- name: Check that change log update was merged to main
run: |
if ! grep --quiet "^## Version $VERSION " CHANGELOG.md; then
echo the pull request generated by prepare-release-branch.yml needs to be merged first
exit 1
fi
# back to the release branch
- uses: actions/checkout@v3
with:
# tags are needed for the generate-release-contributors.sh script
fetch-depth: 0

- name: Generate release notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 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 $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
# conditional block not indented because of the heredoc
cat >> /tmp/release-notes.txt << EOF
### 🙇 Thank you
This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:
EOF
.github/scripts/generate-release-contributors.sh v$PRIOR_VERSION >> /tmp/release-notes.txt
- id: create-github-release
name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create --target $GITHUB_REF_NAME \
--title "Version $VERSION" \
--notes-file /tmp/release-notes.txt \
--discussion-category announcements \
v$VERSION
echo "version=$VERSION" >> $GITHUB_OUTPUT
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Changelog

## Unreleased
Loading

0 comments on commit 1fe2538

Please sign in to comment.